Skip to main content
A newer version of this page is available. .
All docs
V22.2

DialogEditFormBehavior Class

Allows you to enable edit operations in a Data Grid bound to a Server Mode or Instant Feedback data source.

Namespace: DevExpress.Xpf.Grid

Assembly: DevExpress.Xpf.Grid.v22.2.Extensions.dll

NuGet Package: DevExpress.Wpf.Grid.Core

Declaration

public class DialogEditFormBehavior :
    Behavior<GridControl>

Remarks

Server Mode and Instant Feedback sources do not support edit operations out-of-the-box. Use the DialogEditFormBehavior to allow users to invoke a dialog edit form where they can modify row values:

Server Mode and Instant Feedback - Edit Data

  1. Add the DialogEditFormBehavior to Data Grid behaviors. Set its KeyProperty to a key field that you can use to find rows during edit operations.

    <dxg:GridControl x:Name="grid" ItemsSource="{Binding InstantFeedbackSource}">
        <dxmvvm:Interaction.Behaviors>
            <dxg:DialogEditFormBehavior x:Name="EditFormBehavior" KeyProperty="Id" />
        </dxmvvm:Interaction.Behaviors>
    </dxg:GridControl>
    
  2. Before a user invokes the dialog edit form, the behavior raises the CreateEditItemViewModel event and executes the CreateEditItemViewModelCommand. Use them to specify a View Model for the edit operation. The View Model includes the item that you want to edit or add to the Data Grid, the data context that describes the edit operation, and the dialog edit form‘s title.

    <dxg:GridControl x:Name="grid" ItemsSource="{Binding InstantFeedbackSource}">
        <dxmvvm:Interaction.Behaviors>
            <dxg:DialogEditFormBehavior x:Name="EditFormBehavior" KeyProperty="Id" 
                CreateEditItemViewModelCommand="{Binding CreateEditEntityViewModelCommand}"/>
        </dxmvvm:Interaction.Behaviors>
    </dxg:GridControl>
    
    [Command]
    public void CreateEditEntityViewModel(CreateEditItemViewModelArgs args) {
        var context = new IssuesContext();
        Issue item;
        if(args.IsNewItem) {
            item = new Issue() { Created = DateTime.Now };
            context.Entry(item).State = EntityState.Added;
        } else {
            item = context.Issues.Find(args.Key);
        }
        args.ViewModel = new EditItemViewModel(
            item,
            new EditIssueInfo(context, Users),
            title: (args.IsNewItem ? "New " : "Edit ") + nameof(Issue)
        );
    }
    
  3. Specify the behavior’s EditTemplate property to define editors in the dialog edit form. In the template, use the data context that you defined in the previous step.

    <dxg:GridControl x:Name="grid" ItemsSource="{Binding InstantFeedbackSource}">
        <dxmvvm:Interaction.Behaviors>
            <dxg:DialogEditFormBehavior x:Name="EditFormBehavior" KeyProperty="Id"
                CreateEditItemViewModelCommand="{Binding CreateEditEntityViewModelCommand}">
                <dxg:DialogEditFormBehavior.EditTemplate>
                    <DataTemplate>
                        <local:IssueDetailView/>
                    </DataTemplate>
                </dxg:DialogEditFormBehavior.EditTemplate>
            </dxg:DialogEditFormBehavior>
        </dxmvvm:Interaction.Behaviors>
    </dxg:GridControl>
    
    <dxlc:LayoutControl x:Name="layoutControl" Orientation="Vertical"
                        VerticalAlignment="Top" Width="300">
        <dxlc:DataLayoutItem Binding="{Binding Item.Subject}"/>
        <dxlc:LayoutItem Label="User">
            <dxe:ComboBoxEdit ItemsSource="{Binding EditOperationContext.Users}"
                              EditValue="{Binding Item.UserId}"
                              ValueMember="Id"
                              DisplayMember="Name"
                              IsTextEditable="False"/>
        </dxlc:LayoutItem>
        <dxlc:DataLayoutItem Binding="{Binding Item.Created}"/>
        <dxlc:DataLayoutItem Binding="{Binding Item.Votes}"/>
        <dxlc:DataLayoutItem Binding="{Binding Item.Priority}"/>
    </dxlc:LayoutControl>
    
  4. Allow users to invoke the dialog edit form with a double click of a row. To do that, bind the view’s RowDoubleClickCommand to the behavior’s RowDoubleClickCommand.

    <dxg:GridControl x:Name="grid" ItemsSource="{Binding InstantFeedbackSource}">
        <dxg:GridControl.View>
            <dxg:TableView NavigationStyle="Row"
                RowDoubleClickCommand="{Binding RowDoubleClickCommand, ElementName=EditFormBehavior}"/>
      </dxg:GridControl.View>
        <!-- ... -->
    </dxg:GridControl>
    

    Alternatively, you can specify InputBindings.

    <dxg:GridControl x:Name="grid" ItemsSource="{Binding InstantFeedbackSource}">
        <!-- ... -->
        <dxg:GridControl.InputBindings>
            <KeyBinding Key="F2" 
                        Command="{Binding UpdateCommand, ElementName=EditFormBehavior}"/>
            <KeyBinding Key="N" Modifiers="Control" 
                        Command="{Binding CreateCommand, ElementName=EditFormBehavior}"/>
        </dxg:GridControl.InputBindings>
    </dxg:GridControl>
    

    You can also bind behavior commands to button actions.

    <dxb:ToolBarControl>
        <dxb:BarButtonItem Content="Edit (F2)" 
                           Command="{Binding UpdateCommand, ElementName=EditFormBehavior}"/>
        <dxb:BarButtonItem Content="New (Ctrl+N)" 
                           Command="{Binding CreateCommand, ElementName=EditFormBehavior}"/>
    </dxb:ToolBarControl> 
    
  5. After a user saves changes made in the dialog edit form, the behavior raises the ValidateRow event and executes the ValidateRowCommand. Use them to validate values, check database constraints, and save changes to the database.

    <dxg:GridControl x:Name="grid" ItemsSource="{Binding InstantFeedbackSource}">
        <dxmvvm:Interaction.Behaviors>
            <dxg:DialogEditFormBehavior x:Name="EditFormBehavior" KeyProperty="Id" 
                    CreateEditItemViewModelCommand="{Binding CreateEditEntityViewModelCommand}" 
                    ValidateRowCommand="{Binding ValidateRowCommand}"/>
        </dxmvvm:Interaction.Behaviors>
    </dxg:GridControl>
    
    [Command]
    public void ValidateRow(EditFormRowValidationArgs args) {
        var context = ((EditIssueInfo)args.EditOperationContext).DbContext;
        context.SaveChanges();
    }
    
  6. Users can remove rows from the Data Grid. To do that, they can select rows and call the DeleteCommand command.

    As a result, the behavior raises the ValidateRowDeletion event and executes the ValidateRowDeletionCommand. Use them to validate rows, check database constraints, and delete rows from the database.

    <dxg:GridControl x:Name="grid" ItemsSource="{Binding InstantFeedbackSource}">
        <dxmvvm:Interaction.Behaviors>
            <dxg:DialogEditFormBehavior x:Name="EditFormBehavior" KeyProperty="Id" 
                    CreateEditItemViewModelCommand="{Binding CreateEditEntityViewModelCommand}" 
                    ValidateRowCommand="{Binding ValidateRowCommand}"
                    ValidateRowDeletionCommand="{Binding ValidateRowDeletionCommand}"/>
        </dxmvvm:Interaction.Behaviors>
    </dxg:GridControl>
    
    [Command]
    public void ValidateRowDeletion(EditFormValidateRowDeletionArgs args) {
        var key = (int)args.Keys.Single();
        var item = new Issue() { Id = key };
        var context = new IssuesContext();
        context.Entry(item).State = EntityState.Deleted;
        context.SaveChanges();
    }
    

    You can also add a KeyBinding to allow users to press Delete to remove selected rows:

    <dxg:GridControl x:Name="grid" ItemsSource="{Binding InstantFeedbackSource}">
        <!-- ... -->
        <dxg:GridControl.InputBindings>
            <KeyBinding Key="Delete" 
                        Command="{Binding DeleteCommand, ElementName=EditFormBehavior}"/>
        </dxg:GridControl.InputBindings>
    </dxg:GridControl>
    

Asynchronous Edit Operations

The DialogEditFormBehavior allows you to process edit operations asynchronously. While such an operation is in progress, users can cancel it or they can continue to interact with other controls on your form.

DialogEditFormBehavior - Async Operations

Create the Edit Operation’s View Model

You can specify the edit operation’s view model in a background thread. The GridControl displays the wait indicator during the operation. Follow the steps below to implement this behavior:

  1. Create a task that specifies a view model for the edit operation.
  2. Create a command and bind it to the DialogEditFormBehavior.CreateEditItemViewModelCommand property.
  3. Assign the task to the command’s GetViewModelAsync property.
<dxg:GridControl ...>
    <dxmvvm:Interaction.Behaviors>
        <dxg:DialogEditFormBehavior x:Name="EditFormBehavior" KeyProperty="Id"
            CreateEditItemViewModelCommand="{Binding CreateEditEntityViewModelCommand}">
            <!-- ... -->
        </dxg:DialogEditFormBehavior>
    </dxmvvm:Interaction.Behaviors>
</dxg:GridControl>
[Command]
public void CreateEditEntityViewModel(CreateEditItemViewModelArgs args) {
    args.GetViewModelAsync = GetViewModel(args);
}

async Task<IEditItemViewModel> GetViewModel(CreateEditItemViewModelArgs args) {
    await Task.Delay(1000);
    var context = new IssuesContext();
    Issue item;
    if (args.IsNewItem) {
        item = new Issue() { Created = DateTime.Now };
        context.Entry(item).State = EntityState.Added;
    } else {
        item = context.Issues.Find(args.Key);
    }
    return new EditItemViewModel(
        item, 
        new EditIssueInfo(context, Users), 
        title: (args.IsNewItem ? "New " : "Edit ") + nameof(Issue)
    );
}

Validate Changes

You can validate changes and save them to the data source in another thread. The dialog edit form displays the wait indicator in the Save button during the operation. Follow the steps below to implement this behavior:

  1. Create a task that validates changes and saves them to the data source.
  2. Create a command and bind it to the DialogEditFormBehavior.ValidateRowCommand property.
  3. Assign the task to the command’s ValidateAsync property.
  4. Set the DialogEditFormBehavior.AllowCancelAsyncOperations property to true to allow users to cancel the asynchronous post changes operation.
<dxg:GridControl ...>
    <dxmvvm:Interaction.Behaviors>
        <dxg:DialogEditFormBehavior x:Name="EditFormBehavior" KeyProperty="Id"
            CreateEditItemViewModelCommand="{Binding CreateEditEntityViewModelCommand}" 
            ValidateRowCommand="{Binding ValidateRowCommand}"
            AllowCancelAsyncOperations="True">
            <!-- ... -->
        </dxg:DialogEditFormBehavior>
    </dxmvvm:Interaction.Behaviors>
</dxg:GridControl>
[Command]
public void ValidateRow(EditFormRowValidationArgs args) {
    args.ValidateAsync = ValidateAsync(args);
}
async Task ValidateAsync(EditFormRowValidationArgs args) {
    await Task.Delay(2000);
    var context = ((EditIssueInfo)args.EditOperationContext).DbContext;
    context.SaveChanges();
    args.CancellationToken.ThrowIfCancellationRequested();
}

Validate the Delete Row Operation

You can delete rows from a data source in a background thread. The GridControl displays the wait indicator during the operation. Follow the steps below to implement this behavior:

  1. Create a task that deletes rows form the data source.
  2. Create a command and bind it to the DialogEditFormBehavior.ValidateRowDeletionCommand property.
  3. Assign the task to the ValidateAsync property.
<dxg:GridControl ...>
    <dxmvvm:Interaction.Behaviors>
        <dxg:DialogEditFormBehavior x:Name="EditFormBehavior" KeyProperty="Id"
            CreateEditItemViewModelCommand="{Binding CreateEditEntityViewModelCommand}" 
            ValidateRowCommand="{Binding ValidateRowCommand}"
            ValidateRowDeletionCommand="{Binding ValidateRowDeletionCommand}"
            AllowCancelAsyncOperations="True">
            <!-- ... -->
        </dxg:DialogEditFormBehavior>
    </dxmvvm:Interaction.Behaviors>
</dxg:GridControl>
[Command]
public void ValidateRowDeletion(EditFormValidateRowDeletionArgs args) {
    args.ValidateAsync = ValidateDeletion(args);
}

async Task ValidateDeletion(EditFormValidateRowDeletionArgs args) {
    await Task.Delay(2000);
    var key = (int)args.Keys.Single();
    var item = new Issue() { Id = key };
    var context = new IssuesContext();
    context.Entry(item).State = EntityState.Deleted;
    context.SaveChanges();
}

Examples

Instant Feedback
Server Mode

The following code snippets (auto-collected from DevExpress Examples) contain references to the DialogEditFormBehavior class.

Note

The algorithm used to collect these code examples remains a work in progress. Accordingly, the links and snippets below may produce inaccurate results. If you encounter an issue with code examples below, please use the feedback form on this page to report the issue.

Inheritance

Object
DispatcherObject
DependencyObject
Freezable
Animatable
DevExpress.Mvvm.UI.Interactivity.AttachableObjectBase
DevExpress.Mvvm.UI.Interactivity.Behavior
DevExpress.Mvvm.UI.Interactivity.Behavior<GridControl>
DialogEditFormBehavior
See Also