Arsen Zahray
Arsen Zahray

Reputation: 25367

WPF DataGrid CellEditEnded event

I'm looking to know every time the user has edited a content of my DataGrid's cell. There's CellEditEnding event, but its called before any changes were made to the collection, that the DataGrid is bound to.

My datagrid is bound to ObservableCollection<Item>, where Item is a class, automatically generated from WCF mex endpoint.

What is the best way to know every time the user has committed the changes to the collection.

UPDATE

I've tried CollectionChanged event, end it does not get triggered when Item gets modified.

Upvotes: 6

Views: 12301

Answers (4)

kxiaocai
kxiaocai

Reputation: 2803

I used "CurrentCellChanged" instead.

    <DataGrid
        Grid.Row="1"
        HorizontalAlignment="Center"
        AutoGenerateColumns="True"
        AutoGeneratingColumn="OnAutoGeneratingColumn"
        ColumnWidth="auto"
        IsReadOnly="{Binding IsReadOnly}"
        ItemsSource="{Binding ItemsSource, UpdateSourceTrigger=PropertyChanged}">
        <b:Interaction.Triggers>
            <!--  CellEditEnding  -->
            <b:EventTrigger EventName="CurrentCellChanged">
                <b:InvokeCommandAction Command="{Binding CellEditEndingCmd}" />
            </b:EventTrigger>
        </b:Interaction.Triggers>
    </DataGrid>

Upvotes: 0

steveybrown
steveybrown

Reputation: 303

You can use UpdateSourceTrigger=PropertyChangedon 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 below

<DataGrid SelectionMode="Single"
          AutoGenerateColumns="False"
          CanUserAddRows="False"
          ItemsSource="{Binding Path=Items}" // This is your ObservableCollection
          SelectedIndex="{Binding SelectedIndexStory}">
          <e:Interaction.Triggers>
              <e:EventTrigger EventName="CellEditEnding">
                 <cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding EditStoryCommand}"/> // Mvvm light relay command
               </e:EventTrigger>
          </e:Interaction.Triggers>
          <DataGrid.Columns>
                    <DataGridTextColumn Header="Description"
                        Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}" /> // Name is property on the object i.e Items.Name
          </DataGrid.Columns>

</DataGrid>

UpdateSourceTrigger = PropertyChanged will change the property source immediately whenever the target property changes.

This will allow you to capture edits to items as adding an event handler to the observable collection changed event does not fire for edits of objects in the collection.

Upvotes: 10

friskm
friskm

Reputation: 366

If you need to know whether the edited DataGrid item belongs to a particular collection, you could do something like this in the DataGrid's RowEditEnding event:

    private void dg_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        // dg is the DataGrid in the view
        object o = dg.ItemContainerGenerator.ItemFromContainer(e.Row);

        // myColl is the observable collection
        if (myColl.Contains(o)) { /* item in the collection was updated! */  }
    }

Upvotes: 0

Damascus
Damascus

Reputation: 6651

You should just add an event handler on your ObservableCollection's CollectionChanged event.

Code snippet:

_listObsComponents.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ListCollectionChanged);

// ...


    void ListCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        /// Work on e.Action here (can be Add, Move, Replace...)
    }

when e.Action is Replace, this means that an object of your list has been replaced. This event is of course triggered after the changes were applied

Have fun!

Upvotes: -1

Related Questions