整理:WPF中應用附加事件製作可以繫結命令的其他事件
阿新 • • 發佈:2018-12-17
目的:應用附加事件的方式定義可以繫結的事件,如MouseLeftButton、MouseDouble等等
一、定義屬於Control的附加事件ControlAttachEvent類
/// <summary> 附加事件 </summary> public static class ControlAttachEvent { #region - 雙擊事件 - public static readonly DependencyProperty PreviewMouseDoubleClickProperty = DependencyProperty.RegisterAttached("PreviewMouseDoubleClick", typeof(ICommand), typeof(ControlAttachEvent), new FrameworkPropertyMetadata(OnCommandChanged)); public static ICommand GetPreviewMouseDoubleClick(Control target) { return (ICommand)target.GetValue(PreviewMouseDoubleClickProperty); } public static void SetPreviewMouseDoubleClick(Control target, ICommand value) { target.SetValue(PreviewMouseDoubleClickProperty, value); } private static void Element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) { Control control = sender as Control; ICommand command = GetPreviewMouseDoubleClick(control); if (command.CanExecute(sender)) { command.Execute(sender); e.Handled = true; } } private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Control control = d as Control; control.PreviewMouseDoubleClick += new MouseButtonEventHandler(Element_PreviewMouseDoubleClick); } #endregion public static DependencyProperty PreviewMouseLeftButtonDownCommandProperty = DependencyProperty.RegisterAttached("PreviewMouseLeftButtonDown",typeof(ICommand),typeof(ControlAttachEvent),new FrameworkPropertyMetadata(null, new PropertyChangedCallback(PreviewMouseLeftButtonDownChanged))); public static void SetPreviewMouseLeftButtonDown(DependencyObject target, ICommand value) { target.SetValue(PreviewMouseLeftButtonDownCommandProperty, value); } public static ICommand GetPreviewMouseLeftButtonDown(DependencyObject target) { return (ICommand)target.GetValue(PreviewMouseLeftButtonDownCommandProperty); } private static void PreviewMouseLeftButtonDownChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) { FrameworkElement element = target as FrameworkElement; if (element != null) { if ((e.NewValue != null) && (e.OldValue == null)) { element.PreviewMouseLeftButtonDown += element_PreviewMouseLeftButtonDown; } else if ((e.NewValue == null) && (e.OldValue != null)) { element.PreviewMouseLeftButtonDown -= element_PreviewMouseLeftButtonDown; } } } private static void element_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { FrameworkElement element = (FrameworkElement)sender; ICommand command = (ICommand)element.GetValue(PreviewMouseLeftButtonDownCommandProperty); command.Execute(sender); } }
說明:當控制元件MyControl中應用該項附加事件,如註冊PreviewMouseDoubleClick事件,則會觸發更新方法OnCommandChanged,而在更新方法中則會註冊該控制元件MyControl的雙擊事件繫結的命令,由此實現雙擊該控制元件觸發繫結命令的功能;
二、呼叫方法
<Button base:ControlAttachEvent.PreviewMouseDoubleClick="{Binding RelayCommand}"/>
如上程式碼當雙擊Button時會觸發ViewModel中繫結的RelayCommand命令
注:
優點在於可以把控制元件中不支援繫結的事件支援繫結,同時應用附加屬性複用性更強
缺點在於傳遞事件的引數只有sender,agrs需要特殊處理,同時支援的事件與Control有關,其他更上層的控制元件需要單獨定義