Reputation: 102733
Using an MVVM pattern in Silverlight/WPF, how do you wire up event handers? I'm trying to bind the XAML Click property to a delegate in the view model, but can't get it to work.
In other words, I want to replace this:
<Button Content="Test Click" Click="Button_Click" />
where Button_Click is:
private void Button_Click(object sender, RoutedEventArgs e)
{
// ...
}
with this:
<Button Content="Test Click" Click="{Binding ViewModel.HandleClick}" />
where HandleClick is the handler. Attempting this throws a runtime exception:
Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.Windows.RoutedEventHandler'.
Upvotes: 1
Views: 2315
Reputation: 25201
The MVVM way to do so is by using commands and the ICommand
interface.
The Button
control has a property named Command
which receives an object of type ICommand
A commonly used implementation of ICommand
is Prism's DelegateCommand
. To use it, you can do this in your view model:
public class ViewModel
{
public ICommand DoSomethingCommand { get; private set; }
public ViewModel()
{
DoSomethingCommand = new DelegateCommand(HandleDoSomethingCommand);
}
private void HandleDoSomethingCommand()
{
// Do stuff
}
}
Then in XAML:
<Button Content="Test Click" Command={Binding DoSomethingCommand} />
Also, make sure that the viewmodel is set as your view's DataContext. One way to do so is in your view's code-behind:
this.DataContext = new ViewModel();
This article is a good place to start if you want to know more about MVVM.
Upvotes: 5
Reputation: 102733
The answer is to use the extensions provided by Microsoft in the Prism framework. With the DLLs System.Windows.Interactivity.dll and Microsoft.Expression.Interactions.dll, it's possible to bind an event to a handler method in a view model:
<Button Content="Test Click"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction TargetObject="{Binding ViewModel}" MethodName="HandleClick" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Upvotes: 0