1
votes

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
If you change the cell back to previous valid state how is user suppose to get notified that he is doing something wrong. He might keep repeating to set -1 in the cell but it will always be changed back to 0. (If 0 was current value before edit). Do you really want this?dev hedgehog
Basically its a small part of my application requirement.. There is an error list, the user selects an error and the focus automatically goes to that element, now if the user selects some other error in the grid, the focus does not change because the old error was not fixed, but I want the focus to change to the new selected error and the grid does not allow to change the editing element. (I am using the WPF Toolkit Grid). I am able to change to focus if the old error was fixed.Rachit Magon
But you will never add any items into that error list since you need to first fix error in cell before leaving cell lol. So again what is the point. Tell us more info why you doing this. Maybe we will find a better suggests for you. The list you are talking about will never get filled.dev hedgehog
I totally get your point.. but my application requirement.. I'm not being able to explain it properly.. I am filling the list by adding the error inside this[columnName] (in my Model inherited from IDataErrorInfo), so the list is getting filled all right. By Validation constraints I basically mean things like "Property should be between 10 and 20". Now lets suppose the user adds a new row, Validations occur on 4 properties so the list will be filled (it is filled, I can give the code if required).Rachit Magon
What I want is the user to be able to navigate between the errors, without necessarily fixing them. (That Error List has other errors too, its like a global error list for the whole application). Would a sample code help ?Rachit Magon

2 Answers

3
votes

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>
1
votes

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>