33
votes

I know that WPF datagrid has "RowEditEnding" event , but I need to fire the event on after the Row has comitted to check if the newly added row is duplicated and merge the duplicated row. My datagrid has "CanUserAddRow" property set to True.

I am using EntityObservableCollection that extends ObservableCollection to synchronize my entity with the collection. So, i considered OnCollectionChanged event, but the "InsertItem" event is raise once user click on the new item place holder row, which means the object is still empty and I cant check for duplicate.

Is there anyway that I can raise the RowEditEnded event?

Thanks...

8
There might have some validating event. u can check that for a while.Sankarann
Did you really try to look enough at CollectionChanged? Checks inside could let you know when item actually inserted or updated, so you could check each time and if fields filled out THEN execute change logic: stackoverflow.com/questions/4587448/collectionchanged-sample. I upvoted @Mah before i realised the limitations of that approach (toggling handles then forcing commit and refresh and ect), and thought more on collectionchanged (but cant remove upvote now)Daniel Brose

8 Answers

34
votes
    private void dgrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        if (this.dgrid.SelectedItem != null)
        {
            (sender as DataGrid).RowEditEnding -=dgrid_RowEditEnding;
            (sender as DataGrid).CommitEdit();
            (sender as DataGrid).Items.Refresh();
            (sender as DataGrid).RowEditEnding += dgrid_RowEditEnding;
        }
        else Return;

       //then check if the newly added row is duplicated
    }
4
votes

You can use UpdateSourceTrigger=PropertyChanged on the binding of the property member for the datagrid. This will ensure that when CellEditEnding is fired the update has already been reflected in the observable collection. see this post https://stackoverflow.com/a/27239243/9285072

3
votes

I found an answer to your question usingVS2010

condition if (e.EditAction == DataGridEditAction.Commit) in the RowEditEnding will fulfill ur requirement

Please see the below code.

private void dataGrid1_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
    if (e.EditAction == DataGridEditAction.Commit)
    {
        MessageBox.Show("asd");
    }
}

This is the Xaml Behind.

<DataGrid AutoGenerateColumns="False" CanUserAddRows="True" Height="241" 
    RowEditEnding="dataGrid1_RowEditEnding" HorizontalAlignment="Left" 
    Name="dataGrid1" VerticalAlignment="Top" Width="573" >
    <DataGrid.Columns>
        <DataGridTextColumn Header="name" Binding="{Binding id}" 
            Width="300">
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>
3
votes

Taking from @MaherBenIssa's answer, I used this to avoid add and remove delegate:

    private bool locker = true;

    private void dgArticles_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        if (locker)
        {
            try{
                locker = false;
                (sender as DataGrid).CommitEdit(DataGridEditingUnit.Row, false);
                ((sender as FrameworkElement).DataContext as ViewModel)?.Edit(e.Row.DataContext);
            }
            finally{
               locker = true; //enable editing again
            }
        }
    }
0
votes

Try setting the CommitEdit() function for your datagrid. I used it here:

private void DataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
{
    this.MyDataGrid.CommitEdit(DataGridEditingUnit.Row, false);
}
0
votes

VB.NET solution to the solution of @MaherBenIssa

Private Sub dgLayer_RowEditEnding(sender As Object, e As DataGridRowEditEndingEventArgs)

    Dim d As DataGrid
    d = DirectCast(sender, DataGrid)

    RemoveHandler d.RowEditEnding, AddressOf dgLayer_RowEditEnding

    dgLayer.CommitEdit()
    sender.Items.Refresh()

    AddHandler d.RowEditEnding, AddressOf dgLayer_RowEditEnding

End Sub
0
votes

Maybe you can use the event "CurrentCellChanged". This fires when you start editing a cell too, but maybe you can find a way to not always do everything you want to do in your method.

I had same problem when i wanted to check if the changes in the datagrid are actually changes to the original values. This event is working for my needs.

Hope i could tell you something new.

-1
votes

I wonder why you are finding the way to raise the RowEditEnded event; if you Implement the RowEditEnding event of datagrid; whenever you edited a row and change the focus from that row, the row will be committed and RowEditEnding will be raised;

so after the Row has committed RowEditEnding will be raised and work just as RowEditEnded;

Did I understand something wrong from your text?