Search code examples
wpfdatagridselectedcelltemplatecelleditingtemplate

Set entire selected DataGrid row template to CellEditingTemplate


I have a question regarding WPF DataGrid. For the sake of IDataErrorInfo validation I would like to set the entire selected row as editing - by that I mean setting every cell's (in that row) data template from CellTemplate to CellEditingTemplate.

This is one column for example:

<DataGridTemplateColumn Header="Note">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>                                    
            <TextBox Name="textBoxNote" Text="{Binding Note, ValidatesOnDataErrors=True}" />                                    
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Note}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Is that possible in XAML (triggers of some kind)? How would I do that in codebehind? I have found the solution with two separate styles as resources and then programamatically toggling between them in Row_Selected and Row_Unselected events, but I would rather use the existing above XAML code for columns (with separate CellTemplate and CellEditingTemplate).

Can anyone point me the right way?

Thanks in advance. Best regards, DB


Solution

  • Ok, I didn't manage to put the whole row into edit mode, but I managed to revalidate the IDataErrorInfo object - kind of forced IDataErrorInfo validation. This was the reason for me wanting to set edit mode on all cells of the row - to bind controls from CellEditingTemplate to object properties with ValidateOnDataErrors = True. Otherwise I added new object to the DataGrid, but properties (except of the edited ones) never got validated.

    In the superclass of all of my model objects (that extends IDataErrorInfo) I added this method:

    public virtual void Revalidate() // never needed to override though
    {
        Type type = this.GetType();
    
        // "touch" all of the properties of the object - this calls the indexer that checks
        // if property is valid and sets the object's Error property 
        foreach (PropertyInfo propertyInfo in type.GetProperties())
        {                
            var indexerProperty = this[propertyInfo.Name];
        }
    }
    

    Now when the user adds new object to DataGrid I manually call myNewObject.Revalidate() method to set the Error property which I check before saving the object to the database.

    Thanks and regards, DB