Skip to main content

Show Built-In Forms to Display, Create, and Edit Items

  • 4 minutes to read

DataGridView supports built-in forms that allow users to create, view, and edit records. This article describes how you can invoke these forms.

DataGridView uses DataFormView to generate data editors for these built-in forms. If you need to associate specific editor types with item fields/properties, refer to the following help topic: Data Form - Editors.

Show Read-Only Forms (View Item Data)

Call the DataGridView.ShowDetailForm method or use the DataGridViewCommands.ShowDetailForm property to show a read-only form with item data:

DevExpress DataGridView for MAUI - Default form to view item values

The following code invokes the default View form for a tapped grid row:

<ContentPage.BindingContext>
    <local:TestOrderRepository/>
</ContentPage.BindingContext>
    <!--...-->
    <dxg:DataGridView ItemsSource="{Binding Orders}"
                      RowTapCommand="{Binding Source={RelativeSource Mode=Self}, Path=Commands.ShowDetailForm}">
    </dxg:DataGridView>
Show BindingContext implementation
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace DXFilteringApp;
public abstract class OrderRepository {
   readonly ObservableCollection<Order> orders;
   public OrderRepository() {
       this.orders = new ObservableCollection<Order>();
   }
   public ObservableCollection<Order> Orders {
       get { return orders; }
   }
}
public class TestOrderRepository : OrderRepository {
   const int orderCount = 20;
   readonly Random random;
   public TestOrderRepository() : base() {
       this.random = new Random((int)DateTime.Now.Ticks);
       for (int i = 0; i < orderCount; i++)
           Orders.Add(GenerateOrder(i));
   }
   Order GenerateOrder(int number) {
       Order order = new Order(
           new DateTime(2022, 9, 1).AddDays(random.Next(0, 60)),
           number % 3 == 0,
           (ProductName)random.Next(Enum.GetNames(typeof(ProductName)).Length),
           random.Next(1, 100),
           (PackagingType)random.Next(Enum.GetNames(typeof(PackagingType)).Length));
       return order;
   }
}
public class Order : INotifyPropertyChanged {
   ProductName productName;
   DateTime date;
   bool fastDelivery;
   int quantity;
   PackagingType packagingType;
   public Order() {
       this.productName = ProductName.Tofu;
       this.date = DateTime.Today;
       this.fastDelivery = false;
       this.quantity = 0;
       this.packagingType = PackagingType.CardboardBox;
   }
   public Order(DateTime date, bool fastDelivery, ProductName productName, int quantity, PackagingType packagingType) {
       this.productName = productName;
       this.date = date;
       this.fastDelivery = fastDelivery;
       this.quantity = quantity;
       this.packagingType = packagingType;
   }
   public ProductName ProductName {
       get { return productName; }
       set {
           if (productName != value) {
               productName = value;
               RaisePropertyChanged("ProductName");
           }
       }
   }
   public int Quantity {
       get { return quantity; }
       set {
           if (quantity != value) {
               quantity = value;
               RaisePropertyChanged("Quantity");
           }
       }
   }

   public DateTime Date {
       get { return date; }
       set {
           if (date != value) {
               date = value;
               RaisePropertyChanged("Date");
           }
       }
   }
   public bool FastDelivery {
       get { return fastDelivery; }
       set {
           if (fastDelivery != value) {
               fastDelivery = value;
               RaisePropertyChanged("FastDelivery");
           }
       }
   }
   public PackagingType PackagingType {
       get { return packagingType; }
       set {
           if (packagingType != value) {
               packagingType = value;
               RaisePropertyChanged("PackagingType");
           }
       }
   }
   public event PropertyChangedEventHandler PropertyChanged;
   protected void RaisePropertyChanged(string name) {
       if (PropertyChanged != null)
           PropertyChanged(this, new PropertyChangedEventArgs(name));
   }
}
public enum PackagingType { CardboardBox, CorrugatedBox, ClingFilm, PlasticBox, Chipboard }
public enum ProductName { Tofu, Chocolade, Ikura, Chai, BostonCrabMeat, RavioliAngelo, IponCoffee, QuesoCabrales }

Show Edit Forms

Call the DataGridView.ShowDetailEditForm method or use the DataGridViewCommands.ShowDetailEditForm command to invoke the Edit form.

The following example shows how to invoke the Edit form for the tapped grid row:

<dxg:DataGridView x:Name="grid" 
                  SelectionMode="None" 
                  ItemsSource="{Binding Orders}"
                  RowTapCommand="{Binding Source={RelativeSource Mode=Self}, Path=Commands.ShowDetailEditForm}">
    <!--...-->
</dxg:DataGridView>

Show New Item Form

Call the DataGridView.ShowDetailNewItemForm method or use the DataGridViewCommands.ShowDetailNewItemForm command to invoke the Add new item form.

The following example shows how to invoke the default Add new item form page:

DevExpress DataGridView for MAUI - Default form for creating new item

<Button Text="Add new item" Grid.Row="0" 
        Command="{Binding Source={Reference grid}, Path=Commands.ShowDetailNewItemForm}"/>
<dxg:DataGridView x:Name="grid" Grid.Row="1"
                  ItemsSource="{Binding Orders}">
    <!--...-->
</dxg:DataGridView>

Delete Rows

Users can tap the Delete button in an edit form to remove the DataGridView item:

DevExpress DataGridView for MAUI -- Delete buttons in forms

Call the DataGridView.DeleteRow method to remove the DataGridView row with the given row handle.

If you implement a custom CRUD form, use the DetailFormViewModelBase.DeleteAsync method or the DetailFormViewModelBase.DeleteCommand property to delete the associated item.

Built-in Form Requirements

DataGridView invokes built-in forms if the following conditions are met:

  • The DataGridView.ItemsSource is not empty or it contains a strongly typed collection.
  • The data source object class has a parameterless constructor.
  • For correct navigation, your app should be a Shell app. Alternatively, you can invoke edit forms from a Navigation Page.

    MainPage = new NavigationPage(new MainPage());
    

If the DataGridView does not manage to automatically create a View Model for a data source object, a System.Exception occurs. Handle the CreateDetailFormViewModel event as described in the following section: Customize Form View Model and Created Data Object.

Customize Form View Model and Created Data Object

DataGridView creates its own view model for displayed forms. You can customize this model in the CreateDetailFormViewModel event handler.

For example, to create a data object with predefined values, handle CreateDetailFormViewModel and assign a DetailFormViewModel or DetailEditFormViewModel object to the e.Result property in the event handler. Assign a source item to be edited to the ViewModel’s Item property:

DevExpress DataGridView for MAUI -- Create a ViewModel manually

<Button Clicked="Button_Clicked" Text="Add new item" />
<dxg:DataGridView x:Name="grid" 
                  CreateDetailFormViewModel="grid_CreateDetailFormViewModel">
    <!--...-->
</dxg:DataGridView>
private void grid_CreateDetailFormViewModel(object sender, DevExpress.Maui.Core.CreateDetailFormViewModelEventArgs e) {
    if (e.DetailFormType == DetailFormType.New) {
        var editItem = new Order(DateTime.Today, true, ProductName.IponCoffee, 55, PackagingType.PlasticBox);
        e.Result = new DetailEditFormViewModel(editItem, isNew: true, context: null);
    }
}
private void Button_Clicked(object sender, EventArgs e) {
    grid.ShowDetailNewItemForm();
}