So as I program my wpf application in MVVM, I have of course finally come upon the case where I would like to register for an UIElement's event following the MVVM pattern. And so I have managed to piece together that you can do this using Behaviors, in particular you could register for (let's say for educational purposes) a button click using a Behavior (There is all these events that each UIElement provides, and for reasons unbeknownst to me you can't bind these in VisualStudio as you can UIElement Properties - the little square beside each property - I wish I knew why not?). So to register for that Button Click on my Button I have the following XAML:
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="Window1" Height="300" Width="300"><Grid><Button Content="Hello" local:ClickBehavior.RightClick="{Binding Foo}”/></Grid></Window>
Simple enough, it even seems to make sense. And my static ClickBehavior class looks as follows:
public static class ClickBehavior { public static DependencyProperty RightClickCommandProperty = DependencyProperty.RegisterAttached("RightClick", typeof(ICommand), typeof(ClickBehavior), new FrameworkPropertyMetadata(null, newPropertyChangedCallback(ClickBehavior.RightClickChanged))); public static void SetRightClick(DependencyObject target, ICommandvalue) { target.SetValue(ClickBehavior.RightClickCommandProperty, value); } public static ICommand GetRightClick(DependencyObject target) { return (ICommand)target.GetValue(RightClickCommandProperty); } private static void RightClickChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) { UIElement element = target as UIElement; if (element != null) { // If we're putting in a new command and there wasn't one already // hook the event if ((e.NewValue != null) && (e.OldValue == null)) { element.MouseRightButtonUp += element_MouseRightButtonUp; } // If we're clearing the command and it wasn't already null // unhook the event else if ((e.NewValue == null) && (e.OldValue != null)) { element.MouseRightButtonUp -= element_MouseRightButtonUp; } } } static void element_MouseRightButtonUp(object sender,MouseButtonEventArgs e) { UIElement element = (UIElement)sender; ICommand command = (ICommand)element.GetValue(ClickBehavior.RightClickCommandProperty); command.Execute(null); } }//End of ClickBehavior
The questions that I have are:
1)why do we use RegisterAttached and not Register?
2) If we define a DependencyProperty called "Bla", then we must provide the methods "SetBla" and "GetBla", correct?
3)How and when do we actually register our button with ClickBehavior? That is, nowhere in the code do we ever call any of the methods that take the parameter DependencyObject target?? Does the Button xaml definition automatically call RightClickChanged(Dependency Object target, DependencyPropertyEventArgs e) passing itself as target? What exactly happens behind the scenes?
I know it's a bit, so much Thanks
MarcinMR