Search code examples
c#wpfdatagridwpf-core

DataGrid CellEditEnding event not firing on a cell editing inside DataGridTemplateColumn


In the MyDatagrid_CellEditEnding(...) event (shown below) I am capturing the edited value of a cell whenever a cell of one of the three columns is edited by a user. After editing cell in second or third column, when I move out of that cell, I can see the CellEditEnding event getting called. But the same is not true for the first column that is a DataGridTemplateColumn column. That is, when I change a date in any cell in the first DataGridTemplateColumn, and move the cursor out of the cell, the CellEditEnding event is not called.

Question: What I may be missing here and how can we make it work? I have seen similar issues and their solutions online (such as this and this), so I'm not sure what I may be missing here.

Note: I'm using latest versions of VS2019 and .NET Core 3.1 on Windows 10 vs1903 - Pro

<Window x:Class="MyTestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        .....
        Title="MainWindow">
    <Grid>
        <DataGrid x:Name="MyDatagrid" AutoGenerateColumns="False" SelectionMode="Single" CellEditEnding="MyDatagrid_CellEditEnding">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Date Modified">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <DatePicker SelectedDate="{Binding DateModified}" BorderThickness="0" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                   <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <DatePicker SelectedDate="{Binding DateModified}" BorderThickness="0" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/>
                <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button x:Name="btnTest" Content="Test" HorizontalAlignment="Left" VerticalAlignment="Top" Click="btnTest_Click"/>
    </Grid>
</Window>

Code:

......
......
string _sDateModified;
string _sFirstName;
string _sLastName;
.....
.....
private void MyDatagrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    DataGridColumn c = e.Column;
    if (c.Header.ToString() == "Date Modified")
        _sDateModified = (e.EditingElement as TextBox).Text;
    else if (c.Header.ToString() == "First Name")
        _sFirstName = (e.EditingElement as TextBox).Text;
    else if (c.Header.ToString() == "Last Name")
        _sLastName = (e.EditingElement as TextBox).Text;
}

Solution

  • You are editing the DatePicker in the CellTemplate and this doesn't cause the CellEditEnding event to fire. The CellTemplate is not supposed to contain any input controls.

    Replace the DatePicker in the CellTemplate with a TextBlock:

    <DataGridTemplateColumn Header="Date Modified">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding DateModified, StringFormat=yyyy-MM-dd}" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
        <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
                <DatePicker SelectedDate="{Binding DateModified, UpdateSourceTrigger=LostFocus}" BorderThickness="0" />
            </DataTemplate>
        </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>
    

    Or set the IsEnabled property of the DatePicker in the CellTemplate to false. Either way, you'll have to enter the edit mode by double clicking on the cell before you can expect the CellEditEnding event to fire.