Create a GridView with Xamarin Forms

Hi friends.

Today I would like to write something about how to create a ListView with a “Grid” layout. Xamarin Forms has not a “DataGrid” component. There are some external Packages like DevExpress data gridTelerik ListView or something on GitHub.

First of all I have created a “Model” that I use to fill the ListView

 using System.ComponentModel;
 
 namespace ListViewWithGrid
 {
     public class ListViewModel: INotifyPropertyChanged
     {
 
         public string Description { get; set; }
         public int Qty { get; set; }
         public bool Ordered { get; set; }
 
         public ListViewModel(string description, int qty, bool ordered){
 
             this.Description = description;
             this.Qty = qty;
             this.Ordered = ordered;
         }
 
         public event PropertyChangedEventHandler PropertyChanged;
     }
 }

It is very simple: three fields with a constructor. I use INPC and PropertyChanged.Fody that injects INotifyPropertyChanged code into properties at compile time (so I have a cleaner code).

Now I create a ContentPage to visualize my data. I don’t use XAML ( I don’t like it too much) and for this simple sample, CSharp is enough.

 using System;
 using System.Collections.ObjectModel;
 using Xamarin.Forms;
 
 namespace ListViewWithGrid
 {
     public class ListViewPage : ContentPage
     {
 
         ObservableCollection<ListViewModel> _data { get; set;}
 
         public ListViewPage()
         {
 
             // Fill my data
             _data = new ObservableCollection<ListViewModel>();
             _data.Add(new ListViewModel("Apples", 1000, false));
             _data.Add(new ListViewModel("Bananas", 2000, true));
             _data.Add(new ListViewModel("Kiwi", 400, true));
 
             // Create my listview
             ListView lv = new ListView() { HasUnevenRows = true};
             lv.ItemsSource = _data;
             lv.ItemTemplate = new DataTemplate(typeof(ListViewTemplate));
 
             this.Content = lv;
         }
 
         private class ListViewTemplate : ViewCell
         {
             public ListViewTemplate(){
 
 
                 // Use labels to visualize my data
                 Label labelDescription = new Label();
                 labelDescription.SetBinding(Label.TextProperty, "Description", stringFormat:"Description {0}");
 
                 Label labelQty = new Label();
                 labelQty.SetBinding(Label.TextProperty, "Qty", stringFormat:"Qty: {0}");
 
                 Label labelOrdered = new Label();
                 labelOrdered.SetBinding(Label.TextProperty, "Ordered", stringFormat:"Ordered {0}");
 
                 StackLayout sl = new StackLayout() { Orientation = StackOrientation.Horizontal, Children={labelDescription, labelQty, labelOrdered}};
 
                 this.View = sl;
 
             }
         }
     }
 }

 

There is nothing to say. A ListView with a DataTemplete (the ViewCell) with three Labels. This is the result:

Screenshot 2017-08-27 15.42.43

Fantastic, with this few rows we have a ListView with all data! Xamarin Forms is fantastic, I know.

By the way, we would like to have our data in a “Grid” so they are more readable. For this, we should use a Xamarin Forms component called Grid. Grid is a very powerful Layout.

I create a new ContentPage to have a ListView with a Grid Layout:

 using System;
 using System.Collections.ObjectModel;
 using Xamarin.Forms;
 
 namespace ListViewWithGrid
 {
     public class ListViewPageGrid : ContentPage
     {
 
         ObservableCollection<ListViewModel> _data { get; set;}
 
         public ListViewPageGrid()
         {
             _data = new ObservableCollection<ListViewModel>();
             _data.Add(new ListViewModel("Apples", 1000, false));
             _data.Add(new ListViewModel("Bananas", 2000, true));
             _data.Add(new ListViewModel("Kiwi", 400, true));
 
             // Crete a grid for "title"
             Grid grid = CreateGrid();
             grid.Children.Add(new Label { Text = "Description", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center}, 0, 1, 0, 1);
             grid.Children.Add(SeparatorV(), 1, 2, 0, 1);
             grid.Children.Add(new Label { Text = "Qty", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 2, 3, 0, 1);
             grid.Children.Add(SeparatorV(), 3, 4, 0, 1);
             grid.Children.Add(new Label { Text = "Ordered", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 4, 5, 0, 1);
 
             grid.Children.Add(SeparatorH(), 0, 5, 1, 2);
 
             // Create the ListView to visualize my data
             ListView lv = new ListView() { HasUnevenRows = true, SeparatorVisibility = SeparatorVisibility.None};
             lv.ItemsSource = _data;
             lv.ItemTemplate = new DataTemplate(typeof(ListViewTemplateGrid));
 
             StackLayout sl = new StackLayout() { Children = {grid, lv}, Spacing = 0};
 
             this.Content = sl;
         }
 
         static Grid CreateGrid()
         {
 
             Grid grid = new Grid(){RowSpacing = 0, ColumnSpacing = 0};
 
             // Define row 
             RowDefinition rd = new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) };
             RowDefinition rdSeparator = new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) };
 
             // Define columns (one for every property I have to visualize)
             ColumnDefinition cdDescription = new ColumnDefinition() { Width = new GridLength(2, GridUnitType.Star) };
             ColumnDefinition cdQty = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
             ColumnDefinition cdOrdered = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
 
             // Add row and columns to grid
             grid.RowDefinitions.Add(rd);
             grid.RowDefinitions.Add(rdSeparator);
 
             grid.ColumnDefinitions.Add(cdDescription);
             grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(2, GridUnitType.Absolute) }); // Separator
             grid.ColumnDefinitions.Add(cdQty);
             grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(2, GridUnitType.Absolute) }); // Separator
             grid.ColumnDefinitions.Add(cdOrdered);
 
             return grid;
         }
 
         static BoxView SeparatorV(){
 
             return new BoxView() { WidthRequest = 2, BackgroundColor = Color.Red };
         }
 
         static BoxView SeparatorH()
         {
 
             return new BoxView() { HeightRequest = 2, BackgroundColor = Color.Red };
         }
 
         class ListViewTemplateGrid : ViewCell
         {
             public ListViewTemplateGrid(){
 
 
                 Label labelDescription = new Label() {VerticalOptions = LayoutOptions.Center};
                 labelDescription.SetBinding(Label.TextProperty, "Description");
 
                 Label labelQty = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
                 labelQty.SetBinding(Label.TextProperty, "Qty");
 
                 Label labelOrdered = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
                 labelOrdered.SetBinding(Label.TextProperty, "Ordered");
 
                 // Add controls to the grid
                 Grid grid = CreateGrid();
                 grid.Children.Add(labelDescription, 0,1,0,1);
                 grid.Children.Add(SeparatorV(), 1, 2, 0, 1);
                 grid.Children.Add(labelQty, 2, 3, 0, 1);
                 grid.Children.Add(SeparatorV(), 3, 4, 0, 1);
                 grid.Children.Add(labelOrdered, 4, 5, 0, 1);
 
                 grid.Children.Add(SeparatorH(), 0, 5, 1, 2);
 
                 this.View = grid;
 
             }
         }
     }
 }

 

CreateGrid() is the function that creates a Grid with two rows and five columns. One row and two columns are used to add separators. For “data” columns, I use “Star” as GridUnitType so the Grid has proportional columns (“Description” columns has a width “double” than the others). I use CreateGrid() two times: first time is for the Title, second time is inside the ViewCell to visualize my data.

SeparatorV() and SeparatorH() create “separators” (they are tiny BoxViews). You can also not use separators, or use ListView’ Separator (I have hide it in this example with SeparatorVisibility = SeparatorVisibility.None), but this is only for horizontal separation; if you don’t want to add separators to the Grid, remove last row and columns 1 and 3 from CreateGrid().

With this code, I have this result.

Screenshot 2017-08-27 17.00.39

I think a more readable ListView.

This is iOS:

Screenshot 2017-08-27 21.06.59

You can find the code on GitHub.

Obviously, you can add other styles or “commands” to this GridView.

What do you think?

7 pensieri su “Create a GridView with Xamarin Forms

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...