Значение измененного значения ячейки WPF DataGrid

У меня есть настройка, которая выглядит так:

// myDG is a DataGrid whose columns are DataGridTextColumn
ObservableCollection<MyItem> myOC;
// myOC is populated with some new MyItem
myDG.ItemsSource = myOC;

где MyItem реализует INotifyPropertyChanged. Каким образом правильно поймать, когда пользователь вводит значение в ячейку?

Я попытался поймать PropertyChanged на MyItem s, но я также периодически обновляю значения в фоновом режиме (идея состоит в том, что когда пользователь вручную редактирует значение, запускается флаг, который сообщает периодический расчет чтобы избежать перезаписи введенных вручную данных). Таким образом, PropertyChanged ловит все, включая периодические обновления, которых я не хочу. Я полагаю, что это возможно сделать (установив флаг, когда я делаю периодический расчет, а затем проверяю отсутствие флага в обработчике события PropertyChanged, но я хочу знать, есть ли более простое решение.)

Я пробовал ловлю myDG.CurrentCellChanged, но это срабатывало каждый раз, когда пользователь менял выбор ячейки, а не конкретно, когда редактировал содержимое ячеек.

Изменить: Вот XAML:

<DataGrid x:Name="myDG" ItemsSource="{Binding}" AutoGenerateColumns="False" Margin="10,10,182,0" VerticalAlignment="Top" Height="329" ClipboardCopyMode="IncludeHeader">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Col1" Binding="{Binding Prop1}" IsReadOnly="True"/>
        <DataGridTextColumn Header="Col2" Binding="{Binding Prop2}" IsReadOnly="False"/>
    </DataGrid.Columns>
</DataGrid>

Вот реализация MyItem (использует Fody/PropertyChanged):

[ImplementPropertyChanged]
class MyItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string Prop1 { get; set; }
    public string Prop2 { get; set; }

    public MyItem()
    {
        Prop1 = Prop2 = "";
    }
}

Ответ 1

Решение заключалось в том, чтобы поймать событие CellEditEnding.

// In initialization
myDG.CellEditEnding += myDG_CellEditEnding;

void myDG_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    if (e.EditAction == DataGridEditAction.Commit)
    {
        var column = e.Column as DataGridBoundColumn;
        if (column != null)
        {
            var bindingPath = (column.Binding as Binding).Path.Path;
            if (bindingPath == "Col2")
            {
                int rowIndex = e.Row.GetIndex();
                var el = e.EditingElement as TextBox;
                // rowIndex has the row index
                // bindingPath has the column binding
                // el.Text has the new, user-entered value
            }
        }
    }
}

Ответ 2

Вы можете достичь этого с помощью события CellEditEnding , а в DataGridTextColumn нужно добавить некоторые атрибуты, как показано ниже: -

<DataGrid x:Name="myDG" CellEditEnding="myDG_CellEditEnding"  ItemsSource="{Binding}" AutoGenerateColumns="False" Margin="10,10,182,0" VerticalAlignment="Top" Height="329" ClipboardCopyMode="IncludeHeader">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Col1" Binding="{Binding Prop1}" 
 IsReadOnly="True"/>
 <DataGridTextColumn x:Name="dataGridTextColumn"Header="Col2" Binding="{Binding Prop2,  UpdateSourceTrigger=LostFocus, Mode=TwoWay}" Width="*" />
    </DataGrid.Columns>
</DataGrid>

IN С#

 private void myDG_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) {
            string prop1 = (e.Row.Item as DataRowView).Row[1].ToString();
        }