Jacob
Jacob

Reputation: 3698

ObservableCollection Fires Event On Completed

I work on a WPF project build in MVVM architecture. My ViewModel class contains ObservableCollection of SentenceVM class which is also a ViewModel class (implements INotifyPropertyChanged).

This ObservableCollection bound to a DataGrid and I would like to allow adding new records to the collection via the DataGrid build in function.

ObservableCollection<SentenceVM> observe = new ObservableCollection<SentenceVM>()

The problem is that the CollectionChanged event fires at the beginning of the adding row procedure. Thus, I don't know when to refer to the database to submit the new data.

I need this event to be fired when the user has finished adding the new data, not at the beginning.

I know it could be done by generating a command which executes on END inserting or on Enter key but i'm looking for a practical way to do so with this ObservableCollection.

Thank you !

Upvotes: 0

Views: 592

Answers (2)

Mike Eason
Mike Eason

Reputation: 9713

The problem is that the CollectionChanged event fires at the beginning of the adding row procedure. Thus, I don't know when to refer to the database to submit the new data.

In my opinion, there's nothing wrong with inserting the data into the database inside the CollectionChanged event. In fact, the NotifyCollectionChangedEventArgs gives you everything you need in order to perform this action.

Consider looking at e.NewItems, and e.OldItems. The NewItems is the data that is being inserted into the collection, you can simply iterate through this list and act accordingly.

Upvotes: 0

Jacob
Jacob

Reputation: 3698

I found out there is no way to do so via ObservableCollection. The only way to do so in practical way is to define an 'EventToCommand' trigger which executes on CellEditEnding event and execute the bounded command, like that:

1) Define the trigger class which inherits from the TriggerAction class and define the invoke method:

public class EventToCommandTrigger : TriggerAction<FrameworkElement>

2) Define the ICommand (dependency property) to bound to:

public ICommand CommandToExecute
{
    get { return (ICommand)GetValue(CommandToExecuteProperty); }
    set { SetValue(CommandToExecuteProperty, value); }
}
public static readonly DependencyProperty CommandToExecuteProperty =
        DependencyProperty.Register("CommandToExecute", typeof(ICommand), typeof(EventToCommandTrigger), new FrameworkPropertyMetadata(null));

3) Implement the abstract Invoke method like that:

protected override void Invoke(object parameter)
{
    if (CommandToExecute == null)
        return;
    if (CommandToExecute.CanExecute(parameter))
        CommandToExecute.Execute(parameter);
}

4) Then in the xaml code, connect the CellEditEnding event to the above trigger, like that:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="CellEditEnding">
        <triggers:EventToCommandTrigger CommandToExecute="{Binding Path=DeleteCommand}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

Upvotes: 1

Related Questions