Skip to main content

DataGridView.Columns Property

Provides access to the grid’s collection of columns.

Namespace: DevExpress.Maui.DataGrid

Assembly: DevExpress.Maui.DataGrid.dll

NuGet Package: DevExpress.Maui.DataGrid

Declaration

public GridColumnCollection Columns { get; }

Property Value

Type Description
GridColumnCollection

A collection of grid columns.

Remarks

The grid stores its columns in the Columns collection. This collection provides methods that allow you to add, access and remove columns. To access only columns that are currently displayed in the grid, use the DataGridView.VisibleColumns property.

An individual column is a GridColumn class descendant that corresponds to the type of data this column displays. The following column types are supported:

Column Object

Description

TextColumn

A grid column used to display and edit text values.

NumberColumn

A grid column used to display and edit numeric values.

DateColumn

A grid column used to display and edit date values.

CheckBoxColumn

A grid column that displays Boolean values and allows a user to change a cell value by switching between two states.

ImageColumn

A grid column used to display images.

PickerColumn

A grid column that allows a user to edit a cell value by selecting an item from the predefined set.

TemplateColumn

A column type that allows you to define a custom template for column cells.

Create Columns and Bind Them to Data Fields

Columns can be added to a grid and associated with the bound data source’s fields in the following ways:

  • The grid creates columns for all fields of the bound data source.

    A DataGridView instance automatically generates columns based on the bound data source - one column for one field of a data source object, except for complex fields. In terms of objects, a complex field can be a field of a nested object. A complex field name is constructed in the “ClassName.PropertyName” form.

    For example, in Lesson 1 of the Getting Started tutorial, a grid displays orders. When you bind the grid to the collection of Order objects, it automatically generates columns for the order’s Date, Shipped and Quantity properties. However columns for fields of a related product (the order’s Product property returns the Product object) are not created. You can manually add columns to the grid and bind them to the “Product.Name” and “Product.UnitPrice” complex field, as shown in Lesson 2.

    The sequence of columns generated automatically in the grid is the same as the sequence of fields in the data source. You can use the AutoGenerateColumnsMode property to prevent columns from being automatically created or set another mode of auto generating columns.

  • You can create columns and bind them to fields.

    You can specify a collection of grid columns manually. To do this, create column objects that correspond to types of data these columns should display, set each column’s GridColumn.FieldName property to the corresponding field of the bound data source, and add columns to the DataGridView.Columns collection in the order you want them to be displayed in the grid.

Example

This example shows how to create columns in DataGridView to display and edit data of different types. The grid is bound to a collection of Employee objects. Each Employee object contains an employee’s photo (image), name, position, phone, address (strings), hire and birth dates (DateTime values), employee’s access level (enumeration value), and a Boolean value indicating whether an employee is on vacation.

Grid Columns

Add the following columns to the DataGridView.Columns collection:

Grid Column

Description

Photo

ImageColumn

This column displays photos of employees.

Employee

TemplateColumn

This column displays names, positions and hire dates of employees.

Assign a template to the TemplateColumn.DisplayTemplate property to define the presentation of column cells. Each cell contains a Grid with three Label elements bound to the Name, Position and HireDate properties of the Employee class.

The CellData object specifies a binding context for a cell template. Its CellData.Value property provides access to a value of a data field assigned to the column’s GridColumn.FieldName property. In this example, a column cell displays not only this field value but also the values of two more fields. Use the CellData.Item property to access the whole data row object (Employee) and bind its properties to properties of labels defined in the template.

Use the GridColumn.AllowSort and GridColumn.IsReadOnly properties to prevent end users from sorting data by this column and disable data editing.

Phone, Address

TextColumn

These columns are bound to the Phone and Address properties of the string type. The keyboard for text input appears when a user activates a cell to edit an employee’s phone or address.

Birth Date

DateColumn

This column displays birth days of employees and allows end users to edit dates. The GridColumn.DisplayFormat property specifies the date display format.

Access Level

PickerColumn

The AccessLevel enumeration lists values (Admin or User) that specify the employee’s Access property. In a picker column, a user can select between predefined values to change an employee’s access level.

On Vacation

CheckBoxColumn

This column is bound to the employee’s OnVacation property of the Boolean type. A checkbox column allows a user to select between two states when editing cell values.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://schemas.microsoft.com/dotnet/2021/maui/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:dxg="clr-namespace:DevExpress.Maui.DataGrid;assembly=DevExpress.Maui.DataGrid"
             mc:Ignorable="d"
             xmlns:local="clr-namespace:DataGrid_Columns"
             x:Class="DataGrid_Columns.MainPage">
    <ContentPage.BindingContext>
        <local:EmployeeDataViewModel/>
    </ContentPage.BindingContext>
    <dxg:DataGridView ItemsSource="{Binding Employees}" EditorShowMode="DoubleTap">
        <dxg:DataGridView.Columns>
            <dxg:ImageColumn FieldName="Photo"  
                             Width="100" VerticalContentAlignment="Center"/>
            <dxg:TemplateColumn FieldName="Name" Caption="Employee" 
                                IsReadOnly="true" AllowSort="False" MinWidth="200">
                <dxg:TemplateColumn.DisplayTemplate>
                    <DataTemplate>
                        <Grid VerticalOptions="Center" Padding="15, 0, 0, 0">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Text="{Binding Item.Name}" Font="Bold, 18" Grid.Row="0" />
                            <Label Text="{Binding Item.Position, StringFormat = 'Job Title: {0}'}"
                                   Font="Small" Grid.Row="1"/>
                            <Label Text="{Binding Item.HireDate, StringFormat = 'Hire Date: {0:d}'}" 
                                   Font="Small" Grid.Row="2" />
                        </Grid>
                    </DataTemplate>
                </dxg:TemplateColumn.DisplayTemplate>
            </dxg:TemplateColumn>
            <dxg:TextColumn FieldName="Phone" 
                            MinWidth="130" VerticalContentAlignment="Center" />
            <dxg:TextColumn FieldName="Address" 
                            MinWidth="150" VerticalContentAlignment="Center" />
            <dxg:DateColumn FieldName="BirthDate" 
                            MinWidth="120" DisplayFormat="d" VerticalContentAlignment="Center"/>
            <dxg:PickerColumn FieldName="Access" Caption="Access Level" 
                              MinWidth="140" VerticalContentAlignment="Center"/>
            <dxg:CheckBoxColumn FieldName="OnVacation" 
                                MinWidth="130" VerticalContentAlignment="Center"/>
        </dxg:DataGridView.Columns>
    </dxg:DataGridView>
</ContentPage>
using System;
using Microsoft.Maui.Controls;
using System.Collections.ObjectModel;

namespace DataGrid_Columns {
    public enum AccessLevel {
        Admin,
        User
    }

    public class Employee {
        string name;
        string resourceName;

        public string Name {
            get { return name; }
            set {
                name = value;
                if (Photo == null) {
                    resourceName = "DataGrid_Columns.Images." + value.Replace(" ", "_") + ".jpg";
                    if (!String.IsNullOrEmpty(resourceName))
                        Photo = ImageSource.FromResource(resourceName);
                }
            }
        }

        public Employee(string name) {
            this.Name = name;
        }

        public ImageSource Photo { get; set; }
        public DateTime BirthDate { get; set; }
        public DateTime HireDate { get; set; }
        public string Position { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public AccessLevel Access { get; set; }
        public bool OnVacation { get; set; }
    }

    public class EmployeeData {
        void GenerateEmployees() {
            ObservableCollection<Employee> result = new ObservableCollection<Employee>();
            result.Add(
                new Employee("Nancy Davolio") {
                    BirthDate = new DateTime(1978, 12, 8),
                    HireDate = new DateTime(2005, 5, 1),
                    Position = "Sales Representative",
                    Address = "98122, 507 - 20th Ave. E. Apt. 2A, Seattle WA, USA",
                    Phone = "(206) 555-9857",
                    Access = AccessLevel.User,
                    OnVacation = false
                }
            );
            result.Add(
                new Employee("Andrew Fuller") {
                    BirthDate = new DateTime(1965, 2, 19),
                    HireDate = new DateTime(1992, 8, 14),
                    Position = "Vice President, Sales",
                    Address = "98401, 908 W. Capital Way, Tacoma WA, USA",
                    Phone = "(206) 555-9482",
                    Access = AccessLevel.Admin,
                    OnVacation = false
                }
            );
            result.Add(
                new Employee("Janet Leverling") {
                    BirthDate = new DateTime(1985, 8, 30),
                    HireDate = new DateTime(2002, 4, 1),
                    Position = "Sales Representative",
                    Address = "98033, 722 Moss Bay Blvd., Kirkland WA, USA",
                    Phone = "(206) 555-3412",
                    Access = AccessLevel.User,
                    OnVacation = false
                }
            );
            result.Add(
                new Employee("Margaret Peacock") {
                    BirthDate = new DateTime(1973, 9, 19),
                    HireDate = new DateTime(1993, 5, 3),
                    Position = "Sales Representative",
                    Address = "98052, 4110 Old Redmond Rd., Redmond WA, USA",
                    Phone = "(206) 555-8122",
                    Access = AccessLevel.User,
                    OnVacation = false
                }
            );
            result.Add(
                new Employee("Steven Buchanan") {
                    BirthDate = new DateTime(1955, 3, 4),
                    HireDate = new DateTime(1993, 10, 17),
                    Position = "Sales Manager",
                    Address = "SW1 8JR, 14 Garrett Hill, London, UK",
                    Phone = "(71) 555-4848",
                    Access = AccessLevel.User,
                    OnVacation = true
                }
            );
            result.Add(
                new Employee("Michael Suyama") {
                    BirthDate = new DateTime(1981, 7, 2),
                    HireDate = new DateTime(1999, 10, 17),
                    Position = "Sales Representative",
                    Address = "EC2 7JR, Coventry House Miner Rd., London, UK",
                    Phone = "(71) 555-7773",
                    Access = AccessLevel.User,
                    OnVacation = false
                }
            );
            result.Add(
                new Employee("Robert King") {
                    BirthDate = new DateTime(1960, 5, 29),
                    HireDate = new DateTime(1994, 1, 2),
                    Position = "Sales Representative",
                    Address = "RG1 9SP, Edgeham Hollow Winchester Way, London, UK",
                    Phone = "(71) 555-5598",
                    Access = AccessLevel.User,
                    OnVacation = false
                }
            );
            result.Add(
                new Employee("Laura Callahan") {
                    BirthDate = new DateTime(1985, 1, 9),
                    HireDate = new DateTime(2004, 3, 5),
                    Position = "Inside Sales Coordinator",
                    Address = "98105, 4726 - 11th Ave. N.E., Seattle WA, USA",
                    Phone = "(206) 555-1189",
                    Access = AccessLevel.User,
                    OnVacation = true
                }
            );
            result.Add(
                new Employee("Anne Dodsworth") {
                    BirthDate = new DateTime(1980, 1, 27),
                    HireDate = new DateTime(2004, 11, 15),
                    Position = "Sales Representative",
                    Address = "WG2 7LT, 7 Houndstooth Rd., London, UK",
                    Phone = "(71) 555-4444",
                    Access = AccessLevel.User,
                    OnVacation = false
                }
            );
            Employees = result;
        }

        public ObservableCollection<Employee> Employees { get; private set; }

        public EmployeeData() {
            GenerateEmployees();
        }
    }
}

Unbound Columns

In addition to columns bound to data source fields, you can create unbound columns to display values calculated according to a custom logic. To create an unbound column in the grid, add a column object that corresponds to the type of data the column should display to the Columns collection and set the following column properties:

  • GridColumn.FieldName - a unique string that does not match any field name in the grid’s underlying data source.
  • GridColumn.UnboundType - the type of data the column should display (Boolean, DateTime, Decimal, Integer, String or Object).

After a column is created, use one of the following approaches to implement a custom logic for populating an unbound column with data:

  • Set the GridColumn.UnboundExpression property to a formula (string expression) that should calculate column values. You can use values of other columns, constants, various functions and operators in expressions.

  • Handle the DataGridView.CustomUnboundData event. It allows you to provide data for unbound columns and save the changes end users made in these columns.

You can sort, group, display summaries and filter unbound columns in the same manner as bound columns. To make an unbound column read-only, set the DataGridView.IsReadOnly property to true.

Note

The DataGridView cannot operate with only unbound columns. It must be bound to a data source using its DataGridView.ItemsSource property.

Example

Assume that the DataGridView instance is bound to a collection of orders. An order has the Product.Name, Product.UnitPrice and Quantity fields. This example shows how to add an unbound column (Total) to the grid to calculate each order amount according to the expression: UnitPrice*Quantity.

Implement logic to calculate column values in one of the following ways:

  • Use the GridColumn.UnboundExpression property:

    <dxg:DataGridView x:Name="grid" ItemsSource="{Binding Orders}">
        <dxg:DataGridView.Columns>
            <dxg:TextColumn FieldName="Product.Name" Caption="Product" Width="170" />
            <dxg:NumberColumn FieldName="Product.UnitPrice" Caption="Price" DisplayFormat="C0"/>
            <dxg:NumberColumn FieldName="Quantity"/>
            <dxg:NumberColumn FieldName="Total" UnboundType="Integer"
                            UnboundExpression="[Quantity] * [Product.UnitPrice]" 
                            IsReadOnly="True" DisplayFormat="C0"/>
        </dxg:DataGridView.Columns>
    </dxg:DataGridView>
    
  • Handle the DataGridView.CustomUnboundData event:

    <dxg:DataGridView x:Name="grid" 
                      ItemsSource="{Binding Orders}" 
                      CustomUnboundData="Grid_CustomUnboundData">
        <dxg:DataGridView.Columns>
            <dxg:TextColumn FieldName="Product.Name" Caption="Product" Width="170" />
            <dxg:NumberColumn FieldName="Product.UnitPrice" Caption="Price" DisplayFormat="C0"/>
            <dxg:NumberColumn FieldName="Quantity"/>
            <dxg:NumberColumn FieldName="Total" UnboundType="Decimal"
                              IsReadOnly="True" DisplayFormat="C0"/>
        </dxg:DataGridView.Columns>
    </dxg:DataGridView>
    
    // Returns the total for a specific row.
    decimal getTotalValue(DataGridView grid, int rowHandle) {
        decimal unitPrice = Convert.ToDecimal(grid.GetCellValue(rowHandle, "Product.UnitPrice"));
        decimal quantity = Convert.ToDecimal(grid.GetCellValue(rowHandle, "Quantity"));
        return unitPrice * quantity;
    }
    
    // Provides data for the Total column.
    void Grid_CustomUnboundData(object sender, CustomUnboundDataEventArgs e) {
        if (e.Column.FieldName == "Total" && e.IsGetData)
            e.Value = getTotalValue((DataGridView)sender, e.SourceIndex);
    }
    

Identify and Access Columns

When creating a column in XAML, you can use the x:Name attribute to uniquely identify a column and then access it by the specified name from code-behind:

<dxg:DataGridView.Columns>
    <dxg:TextColumn x:Name="colProduct" FieldName="ProductName"/>
    <dxg:NumberColumn x:Name="colUnitPrice" FieldName="UnitPrice"/>
</dxg:DataGridView.Columns>
colUnitPrice.AllowSort = false;

You can also access a column from the grid’s Columns collection by the name of the field to which the column is bound or by the column index in the collection:

<dxg:DataGridView.Columns>
    <dxg:TextColumn FieldName="ProductName"/>
    <dxg:NumberColumn FieldName="UnitPrice"/>
</dxg:DataGridView.Columns>
TextColumn colProduct = (TextColumn)grid.Columns["ProductName"];
NumberColumn colPrice = (NumberColumn)grid.Columns[1];

The column collection also provides the GridColumnCollection.GetColumnByFieldName method that allows you to access columns by field names.

See Also