Cancel Edit Mode in WPF DataGrid even when validation fires

4.6k views Asked by At

I'm new to wpf, I need to use a WPF DataGrid which has its ItemSource set to an ObservableCollection of type Model, where Model implements the IDataErrorInfo class. The problem I am facing is that if the Model returns a validation string for any property, then the user is unable to exit the edit mode for the cell, I tried rollback & I even tried CancelEdit, but I can't exit the edit mode. I searched on msdn and I found out the its one of DataGrid's property but I need to do the same because of some application requirements.

My Model Class:

public class Model: IDataErrorInfo
{
    public int PropertyName{ get; set; }

    // other properties & methods removed for clarity

    public string this[columnName]
    {
        get
        {
            if (PropertyName< 0)
                return "Error Message";
            else
                return string.Empty;
        }
    }
}

Now if 'PropertyName' is less than 0, the user cannot exit the edit mode of the specific cell.

This link on msdn says in 'Remarks' that

The DataGrid will not exit cell editing mode until the validation error is resolved.

Is there any workaround to exit the cell edit mode even if the Validation has returned an error message? I can't help with the code architecture because I am stuck with DataGrid as well as the 'Model' class. Any help would be appreciated, Thanks a lot in advance.

2

There are 2 answers

3
AudioBubble On BEST ANSWER

Validating WPF DataGrid using IdataErrorInfo, The DataGrid will not exit cell editing mode until the validation error is resolved.

This is true but can overcome with a work around - using the TextBox in the DataGridTemplateColumn.CellEditingTemplate and DataGridTemplateColumn.CellTemplate.

Define a datatemplate for datagrid

    <DataGrid.Resources> 
    .... 
    <DataTemplate x:Key="EditingValueTemplate">
        <TextBox Text="{Binding bindingProp, ValidatesOnDataErrors=True}"
                                  FocusManager.FocusedElement="{Binding RelativeSource=  {RelativeSource Self}}"/>
    </DataTemplate>
</DataGrid.Resources>

assign this data template to CellTemplate and CellEditingTemplate of the data grid

    <DataGrid.Columns>
<DataGridTemplateColumn Header="Value" CellTemplate="{StaticResource EditingValueTemplate}" 
                                        CellEditingTemplate="{StaticResource EditingValueTemplate}" />
</DataGrid.Columns>

In case you want to assign tool tip to show error both cases i.e. cell edit mode and mouse hover cell. You need a style

    <Style x:Key="DatagridCellToolTip" TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
</Style.Triggers>
</Style>

and include this style as well with the above datagrid i.e.

<DataGrid.Columns>
    <DataGridTemplateColumn Header="Value" CellTemplate="{StaticResource EditingValueTemplate}" 
                                            CellEditingTemplate="{StaticResource EditingValueTemplate}" 
                                            CellStyle="{StaticResource DatagridCellToolTip}"/>
</DataGrid.Columns>
0
Felix Keil On

I just recognized this by coincident.

When you replace every DataGridTextColumn to TemplateColumn and just make your Binding to the TextBox you can jump between every TextBox and edit multiple rows even if error is not fixed.

<DataGridTemplateColumn Header="Sample" Width="1*">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
                <TextBox.Text>
                    <Binding Path="SampleB" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <vm:CellDataInfoValidationRule ValidationStep="UpdatedValue"/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>