WPF. Change DataContext on event binding to access code-behind on a MVVM project

1.8k views Asked by At

i'm developing a WPF application with MVVM. At the XAML code i have a Grid with its DataContext pointing to a ViewModel, and i need to know if it is possible to change the DataContext at runtime to access an event at its code-behind.

Code-behind for the view:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.DataContext = new MainViewModel();
        InitializeComponent();
    }

    private void ValidationEvent(object sender, ValidationErrorEventArgs e)
    {
        //Something useful
    }
}

Here is the code that i tried in XAML:

<Grid Validation.Error={Binding Path=ValidationEvent RelativeSource={RelativeSource Self}}/>

The XAML code throws an XamlParseException telling that it is not possible to do the Binding on an "AddErrorHandler", that it is only possible for a DependencyProperty on a DependencyObject.

I don't want to change the DataContext of the Grid because inside it there are elements that access the MainViewModel properties, so i just want to change the DataContext for the Validation.Error event binding... If it is possible...

Thanks.

1

There are 1 answers

2
almulo On BEST ANSWER

Validation.Error is an event, not a property. You can't set Bindings to events.

You can use things like MVVM Light's EventToCommand, or Microsoft's own Interactivity EventTrigger to associate Commands to Events.

But there really isn't anything wrong with just adding a regular event handler in code-behind and calling some viewmodel code from there... Contrary to what many people seem to think, MVVM doesn't forbid the use of code-behind and what you'd be doing is not very different from what an EventToCommand or an EventTrigger are doing under the hood.

First of all, just set the event handler name for the Validation.Error event.

<Grid Validation.Error="ValidationEvent" />

And then in your code-behind do whatever you want.

private void ValidationEvent(object sender, ValidationErrorEventArgs e)
{
    // Something useful

    // Some call to VM code
    (this.DataContext as MainViewModel).SomeMethod();
}

This works independently of your DataContext (as long as you cast this.DataContext to the correct type, of course).

Event handlers don't depend on your DataContext, only Bindings do.