In my opinion, the best way to handle UI events in WPF using view models is to implement Attached Properties
. Here is an example that I use to monitor the LostFocus
event... instead of passing the EventArgs
object through to the view model, I am exposing a basic instance of ICommand
(which you can implement in your view model) that will be called when the focus is lost from the relating TextBox
:
public static DependencyProperty OnLostFocusProperty = DependencyProperty.
RegisterAttached("OnLostFocus", typeof(ICommand), typeof(TextBoxProperties), new
UIPropertyMetadata(null, OnLostFocusChanged));
public static ICommand GetOnLostFocus(DependencyObject dependencyObject)
{
return (ICommand)dependencyObject.GetValue(OnLostFocusProperty);
}
public static void SetOnLostFocus(DependencyObject dependencyObject, ICommand value)
{
dependencyObject.SetValue(OnLostFocusProperty, value);
}
public static void OnLostFocusChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs e)
{
TextBox textBox = dependencyObject as TextBox;
if (e.OldValue == null && e.NewValue != null) textBox.LostFocus += TextBox_LostFocus;
else if (e.OldValue != null && e.NewValue == null) textBox.LostFocus -= TextBox_LostFocus;
}
private static void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
TextBox textBox = sender as TextBox;
ICommand command = GetOnLostFocus(textBox);
if (command != null && command.CanExecute(textBox)) command.Execute(textBox);
e.Handled = false;
}
You would use it like this:
<TextBox Text="{Binding SomeValue}" Attached:TextBoxProperties.OnLostFocus="{Binding
YourCommandName}" />
I'm sure that you can make a few changes to be able to apply it to your situation. If you are not familiar with Attached Properties
, please view the Attached Properties Overview page at MSDN.