Objective
When I was trying to add few items(1-2) to a List View in Xamarin forms inside of a Stack Layout, Its height does not automatically set according to the number of rows and there will be a empty space.
So I tried different things to solve the issue and finally I found a solution.
Solution
The solution is we have to set the Height of the list view according to the height of number of rows manually in code behind.
And also we can solve it using MVVM dynamically. Please click here to go to the article…
Here are steps to Solve the issue..
- Create a new Xamarin forms project with a PCL.
- Add a List View in a Stack layout i the MainPage.(But you can do this in your view page)
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:ListViewApp" x:Class="ListViewApp.MainPage"> <ScrollView> <StackLayout> <BoxView HeightRequest="10" HorizontalOptions="FillAndExpand"/> <Image Grid.Row="0" Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="100" WidthRequest="100" Source = "User.png"> </Image> <Label Text=" Friends " HorizontalOptions="FillAndExpand" BackgroundColor="#C7FCE1" FontSize="Large"/> <ListView x:Name="listViewFriends" HasUnevenRows="true" SeparatorVisibility="Default" VerticalOptions="Fill"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <ViewCell.View> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="20"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="20"/> </Grid.ColumnDefinitions> <Image Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" WidthRequest="40" HeightRequest="40" Source = "Friend.png"> </Image> <Label Grid.Row="0" Grid.Column="2" Text="{Binding Name}" FontSize="Medium" TextColor="#065C2B"/> <Label Grid.Row="1" Grid.Column="2" Text="{Binding Email}" FontSize="Small" TextColor="#6FCF97"/> </Grid> </ViewCell.View> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> <Button Text="Add New Friend" TextColor="White" BackgroundColor="#01148E" FontAttributes="Bold" HorizontalOptions="FillAndExpand"/> <Button Text="Delete Friend" TextColor="White" BackgroundColor="#B61515" FontAttributes="Bold" HorizontalOptions="FillAndExpand"/> </StackLayout> </ScrollView> </ContentPage>
3.Then Bind data to the List View in the code behind.
(You can Bind data using MVVM. But Here I’ll bind a collection in a simple way).
Here I have created a Model called “Friend” to create the collection of Friends.
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace ListViewApp { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); listViewFriends.ItemsSource = GetFriends(); } /// <summary> /// Get Messages to Message List /// </summary> /// <returns></returns> private ObservableCollection<FriendModel> GetFriends() { ObservableCollection<FriendModel> collection = new ObservableCollection<FriendModel>(); try { collection.Add(new FriendModel() { ID = 1, Name = "Friend 1", Email = "friend1@sample.com" }); collection.Add(new FriendModel() { ID = 1, Name = "Friend 1", Email = "friend1@sample.com" }); listViewFriends.HeightRequest = (40 * collection.Count)+(10* collection.Count); } catch (Exception) { throw; } return collection; } } public class FriendModel { public string Name { get; set; } public string Email { get; set; } public int ID { get; set; } } }
4. Then Run the code and you can see a list view with a empty area..
5. So we have to reduce the Height of the List view.
Lets see the XAML structure of the list view. The List view contains a grid view as the template. And the grid view has 2 rows. It consists of a image with has the row-span=2. That means normally the height of one item of the List view is equal to the height of the image.
So then I’ll set the
Height(HeightRequest property of ListView) = Number of items * Height of one Item
I have added the code inside of the GetFriends() Method.
private ObservableCollection<FriendModel> GetFriends() { ObservableCollection<FriendModel> collection = new ObservableCollection<FriendModel>(); try { collection.Add(new FriendModel() { ID = 1, Name = "Friend 1", Email = "friend1@sample.com" }); collection.Add(new FriendModel() { ID = 1, Name = "Friend 1", Email = "friend1@sample.com" }); listViewFriends.HeightRequest = (40 * collection.Count); } catch (Exception) { throw; } return collection; }
6. Then Run the app again.. And you may see the allocated size is now enough for the list view.
7. So What Should we do ?
According to that a Item(row) in a List view acquire extra space other than the height of the controls inside it. Normally it may be 10px.
So we have to add it to the height of the ListView.
HeightRequest = (No.of items * Height of one Item) +(Default space + No.of items)
/// <summary> /// Get Messages to Message List /// </summary> /// <returns></returns> private ObservableCollection<FriendModel> GetFriends() { ObservableCollection<FriendModel> collection = new ObservableCollection<FriendModel>(); try { collection.Add(new FriendModel() { ID = 1, Name = "Friend 1", Email = "friend1@sample.com" }); collection.Add(new FriendModel() { ID = 1, Name = "Friend 1", Email = "friend1@sample.com" }); listViewFriends.HeightRequest = (40 * collection.Count)+(10* collection.Count); } catch (Exception) { throw; } return collection; }
Pingback: Xamarin Forms : ListView Height Change Dynamically, using MVVM and also, Solve Empty Space issue | Xamarin Sharp – Codez with Buddhima
Great post, thanks! What is your approach for rows with variable heights?
LikeLiked by 1 person
@alexkywalker
I used syncfusion list view for that purpose… And it saved my time..
https://www.syncfusion.com/products/xamarin/listview
but, I’ll find a solution for xamarin forms list view and will send you…
LikeLike
If you have a solution for Xamarin forms list view please share it
LikeLike
For ListView Extension
public static class ListViewExtension
{
public static void setListViewHightAuto(this ListView listView, int RowHight)
{
int RowCounter = 0;
foreach (var item in listView.ItemsSource)
{
RowCounter++;
}
listView.HeightRequest = RowHight * RowCounter + 10 * RowCounter;
}
}
LikeLike
Congrats on your post and thank you for sharing. Really helpfull.
LikeLiked by 1 person
You welcome !
LikeLike
I tried this solution, this is working on android but not working on IOS.
Please assist me here.
Thanks,
LikeLiked by 1 person
What is the issue you are having ? Please send me your source code. I’ll check it.
LikeLike
Were you able to resolve this for ios? I’ve a listview inside a stacklayout and changing listview’s height has no impact on listview.
LikeLike
The height will be depend on the data template that you use. can you share the code ?
LikeLike