I have been told that best practice for MVVM is to pass the viewmodel to the view so it has no knowledge of the datacontext before runtime. (System 1)
However every post I find passes the viewmodel into the xaml datacontext which doesn't seem ideal for MVVM. (System 2)
What is the best way to bind datacontext in WPF MVVM? How does this affect event handler binding?
Example: I have a combo box linked to an item in my ViewModel. When I use binding system 2, the combobox selection fires the 'ComboChanged' event. When using binding system 1, the combobox selection changes, but the event does not fire. Once the whole page has loaded, the event will trigger when the combo box is changed manually.
Host (System 1):
public override void Initialise()
{
element = new Plugin(new ViewModel(Credentials));
element.combobox.SelectedIndex = 0;
}
Plugin (System 1):
public Plugin(ViewModel viewModel)
{
InitializeComponent();
ViewModel = viewModel;
this.DataContext = ViewModel;
ViewModel.ComboChanged += new EventHandler<ComboChangedEventArgs>(performComboChanged);
}
ViewModel (System 1):
public ViewModel(Credentials credentials)
{
//Initialisation code
}
Host (System 2):
public override void Initialise()
{
element = new Plugin(Credentials)
element.combobox.SelectedIndex = 0;
}
Plugin (System 2):
public Plugin(Credentials credentials)
{
InitializeComponent();
ViewModel = ((ViewModel)this.DataContext);
ViewModel.Credentials = credentials;
ViewModel.ComboChanged += new EventHandler<ComboChangedEventArgs>(performComboChanged);
}
//Plugin.xaml
<UserControl.DataContext>
<local:ViewModel/>
</UserControl.DataContext>
ViewModel (System 2):
public ViewModel()
{
//Initialisation code
}
Thanks in advance
Regarding your event handling implementation :
To make it short :
I always keep in mind this one time in particular when I had to totally reoganize a big complex view (renaming controls, switching from listbox to gridview, reorganizing grid, etc..) : because my MVVM was clean (strict separation of VM/business from view/presentation) i was able to do so without touching any line from my business logic. This would have been a nightmare if I had bound all my control events directly to my view model.
From here you have (at least) two options :
This post sums up the interaction option : MVVM events