Skip to main content

Lesson 1: Bind Grid to Data

  • 4 minutes to read

The DataGridView is a data-aware control designed to present and manage data in a tabular format. To display data in a grid, bind it to a data source. Note that the unbound mode (add and save records directly to a grid) is not supported and the grid cannot operate without a data source.

Create a New Application and Add a Grid

  1. Create a new Xamarin.Forms cross-platform solution and include the DevExpress Grid component.

    In the main project’s App.xaml.cs file, call the DevExpress.XamarinForms.DataGrid.Initializer.Init() method to prepare DevExpress DataGrid for use in the application.

    using Xamarin.Forms;
    
    namespace DataGrid_GettingStarted {
        public partial class App : Application {
            public App() {
                DevExpress.XamarinForms.DataGrid.Initializer.Init();
                InitializeComponent();
                MainPage = new MainPage();
            }
        }
    }
    

    In the iOS project’s AppDelegate.cs file, call the DevExpress.XamarinForms.DataGrid.iOS.Initializer.Init() method.

    using Foundation;
    using UIKit;
    
    namespace DataGrid_GettingStarted.iOS {
        [Register("AppDelegate")]
        public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate {
            public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
                global::Xamarin.Forms.Forms.Init();
                DevExpress.XamarinForms.DataGrid.iOS.Initializer.Init();
                LoadApplication(new App());
    
                return base.FinishedLaunching(app, options);
            }        
        }
    }
    

    Tip

    If you use the DevExpress Xamarin App v22.1 template to create an application, these method calls are automatically added to the code.

  2. In the MainPage.xaml file of the .NET Standard project containing the shared code, use the dxg prefix to declare a namespace and add a DataGridView to a content page:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:dxg="http://schemas.devexpress.com/xamarin/2014/forms/datagrid"
                 x:Class="DataGrid_GettingStarted.MainPage">
        <dxg:DataGridView x:Name="grid">
        </dxg:DataGridView>
    </ContentPage>
    

Prepare a Data Source

In this example, the DataGridView is bound to data created at runtime.

Declare the Order class that encapsulates an individual data record. Its public properties (Date, Shipped, Product and Quantity) are data source fields.

using System;
using System.ComponentModel;

namespace DataGrid_GettingStarted.DataModel {
    public class Order : ModelObject {
        DateTime date;
        bool shipped;
        Product product;
        int quantity;

        public Order() {
            this.date = DateTime.Today;
            this.shipped = false;
            this.product = new Product ("", 0);
            this.Quantity = 0;
        }

        public Order(DateTime date, bool shipped, Product product, int quantity) {
            this.date = date;
            this.shipped = shipped;
            this.product = product;
            this.quantity = quantity;
        }

        public DateTime Date {
            get { return date; }
            set { if (date != value) {
                    date = value;
                    RaisePropertyChanged("Date");}}
        }

        public bool Shipped {
            get { return shipped; }
            set { if(shipped != value) {
                    shipped = value;
                    RaisePropertyChanged("Shipped");}}
        }

        public Product Product {
            get { return product; }
            set { if (product != value) {
                    product = value; 
                    RaisePropertyChanged ("Product");}}
        }

        public int Quantity {
            get { return quantity; }
            set { if (quantity != value) {
                    quantity = value; 
                    RaisePropertyChanged ("Quantity");}}
        }
    }

    public class Product : ModelObject {
        string name;
        int unitPrice;

        public Product(string name, int unitPrice) {
            this.name = name;
            this.unitPrice = unitPrice;
        }

        public string Name {
            get { return name; }
            set { name = value; }
        }

        public int UnitPrice{
            get { return unitPrice; }
            set { unitPrice = value; }
        }
    }

    public class ModelObject : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string name) {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

A collection of Order objects is the data source for the grid. The Orders property of the TestOrderRepository class returns this collection.

using System;
using System.ComponentModel;
using System.Collections.Generic;
...

namespace DataGrid_GettingStarted.DataModel {
    public abstract class OrderRepository {
        readonly BindingList<Order> orders;

        public OrderRepository() {
            this.orders = new BindingList<Order>();
        }

        public BindingList<Order> Orders {
            get { return orders; }
        }
    }

    public class TestOrderRepository : OrderRepository {

        const int orderCount = 100;
        readonly List<Product> products;
        readonly Random random;

        public TestOrderRepository() : base() {
            this.random = new Random((int)DateTime.Now.Ticks);
            this.products = new List<Product>();

            GenerateProducts();

            for (int i = 0; i < orderCount; i++)
                Orders.Add(GenerateOrder(i));
        }

        Order GenerateOrder(int number) {
            Order order = new Order(new DateTime(2020, 1, 1).AddDays(random.Next(0, 60)), 
                number % 3 == 0, RandomItem<Product>(products), random.Next(1, 100));
            return order;
        }

        T RandomItem<T>(IList<T> list) {
            int index = (int)(random.NextDouble() * 0.99 * (list.Count));
            return list[index];
        }

        void GenerateProducts() {
            products.Add(new Product("Tofu", 50));
            products.Add(new Product("Chocolade", 34));
            products.Add(new Product("Ikura", 70));
            products.Add(new Product("Chai", 3));
            products.Add(new Product("Boston Crab Meat", 36));
            products.Add(new Product("Ravioli Angelo", 18));
            products.Add(new Product("Ipon Coffee", 10));
            products.Add(new Product("Queso Cabrales", 25));
        }
    }
}

Bind a Grid to Data

In the MainPage.xaml file:

  1. Set the content page’s BindingContext to the TestOrderRepository object.
  2. Assign the order collection object (TestOrderRepository.Orders) to the DataGridView.ItemsSource property.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:dxg="http://schemas.devexpress.com/xamarin/2014/forms/datagrid"
             xmlns:vm="clr-namespace:DataGrid_GettingStarted.DataModel"
             x:Class="DataGrid_GettingStarted.MainPage">
    <ContentPage.BindingContext>
        <vm:TestOrderRepository/>
    </ContentPage.BindingContext>
    <dxg:DataGridView x:Name="grid" ItemsSource="{Binding Orders}">
    </dxg:DataGridView>
</ContentPage>

The DataGridView automatically generates columns for data source fields, except for complex fields. In the current example, complex fields are fields of a product related to an order (Product.Name and Product.UnitPrice). The column order in the grid is the same as the field order in the data source.

Grid View

The next lesson provides instructions on how to manage a collection of grid columns (bind columns to complex fields, create an unbound column to display calculated values, adjust column settings and set the column display sequence in the grid).