2015-04-06 57 views
0

您好研究员Overflowers:绑定命令中继到矩形Vs的菜单项(CanExecute()不叫)

我有一个是在几个不同的情况下使用中继命令类。 当我绑定到矩形(形状)不调用CanExecute()方法。但是,当我将相同的类绑定到MenuItem时,CanExecute()被调用。它似乎在我开始查看菜单时被调用。当CanExecute重新显示false时,我的菜单项变灰。很好!但是,我的应用程序有很多具有CanExecute实现的形状。到目前为止,我必须从我的Excecute()方法为Shapes调用CanExecute。顺便提一下,我在构建MouseBehaviors时绑定了Shapes。

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Diagnostics; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Input; 

namespace Sweeper.ViewModels 
{ 
    public class 
     RelayCommand : ICommand 
    { 
     #region Fields 

     private readonly Action<object> _execute; 
     private readonly Predicate<object> _canExecute; 
     private readonly Action<object> _unexecute; 
     private string _displayText; 
     private string _category; 

     private static EventHandler newLogItemEvent; 
     public static event EventHandler NewLogItemEvent 
     { 
      add { newLogItemEvent += value; } 
      remove { newLogItemEvent -= value; } 
     } 
     protected virtual void OnNewLogItemEvent(LogItem li) 
     { 
      if (newLogItemEvent != null) 
      { 
       newLogItemEvent(null,li); 
      } 
     } 
     private void RaiseNewLogItemEvent(LogItem li) 
     { 
      OnNewLogItemEvent(li); 
     } 
     // 
     public string Category 
     { 
      get { return _category; } 
      set { _category = value; } 
     } 

     #endregion // Fields 

     #region Constructors 

     //<summary> 
     //Creates a new command that can always execute. 
     //</summary> 
     //<param name="execute">The execution logic.</param> 
     public RelayCommand(Action<object> execute) 
      : this(execute, null) 
     { 

     } 

     //<summary> 
     //Creates a new command. 
     //</summary> 
     //<param name="execute">The execution logic.</param> 
     //<param name="canExecute">The execution status logic.</param> 
     public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
      : this(execute, canExecute, "") 
     { 
     } 

     public RelayCommand(Action<object> execute, Predicate<object> canExecute, string displayText) 
     { 
      if (execute == null) 
       throw new ArgumentNullException("execute"); 

      _execute = execute; 
      _canExecute = canExecute; 
      _displayText = displayText; 
     } 


     public string DisplayText 
     { 
      get { return _displayText; } 
      set { _displayText = value; 
        } 
     } 

     #endregion // Constructors 

     #region ICommand Members 

     // [DebuggerStepThrough] 
     public bool CanExecute(object parameter) 
     { 
      if (_canExecute == null) 
       return true; 
      else 
       return _canExecute(parameter); 

     } 

     public event EventHandler CanExecuteChanged 
     { 
      add { CommandManager.RequerySuggested += value; } 
      remove { CommandManager.RequerySuggested -= value; } 
     } 

     public void Execute(object parameter) 
     { 
      bool sendLogItem = false; 
      if (_canExecute != null) 
      { 
       if (_canExecute(parameter)) 
       { 
        _execute(parameter); 
        sendLogItem = true; 

       } 
      } 
      else 
      { 
       _execute(parameter); 
       sendLogItem = true; 
      } 

      if (sendLogItem) 
      { 
       string str; 
       str = "Cmd:(" + _displayText + ")\tParm:(" + parameter + ")"; 
       RaiseNewLogItemEvent(new LogItem(this, str, parameter, _category)); 
      } 
      else 
      { //Rejected 
      } 
     } 
     #endregion // ICommand Members 

    } 

只是要彻底的,我会在接下来的代码块张贴在安装矩形使用的beaviors对象

namespace Sweeper.Views 
{ 
    public class MouseBehavior 
    { 
     #region MouseUp 

     public static readonly DependencyProperty MouseUpCommandProperty = 
      DependencyProperty.RegisterAttached("MouseUpCommand", typeof(ICommand), typeof(MouseBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseUpCommandChanged))); 

     private static void MouseUpCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseUp += element_MouseUp; 
     } 

     static void element_MouseUp(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseUpCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseUpCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseUpCommandProperty, value); 
     } 

     public static ICommand GetMouseUpCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseUpCommandProperty); 
     } 

     #endregion 

     #region MouseDown 


     public static readonly DependencyProperty MouseDownCommandProperty = 
      DependencyProperty.RegisterAttached("MouseDownCommand", typeof(ICommand), typeof(MouseBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseDownCommandChanged))); 

     private static void MouseDownCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseDown += element_MouseDown; 
     } 

     static void element_MouseDown(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseDownCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseDownCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseDownCommandProperty, value); 
     } 

     public static ICommand GetMouseDownCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseDownCommandProperty); 
     } 

     #endregion 

     #region MouseEnter 

     public static readonly DependencyProperty MouseEnterCommandProperty = 
      DependencyProperty.RegisterAttached("MouseEnterCommand", typeof(ICommand), typeof(MouseBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseEnterCommandChanged))); 

     private static void MouseEnterCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseEnter += new MouseEventHandler(element_MouseEnter); 
     } 

     static void element_MouseEnter(object sender, MouseEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseEnterCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseEnterCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseEnterCommandProperty, value); 
     } 

     public static ICommand GetMouseEnterCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseEnterCommandProperty); 
     } 
     #endregion 

     #region MouseLeave 

     public static readonly DependencyProperty MouseLeaveCommandProperty = 
      DependencyProperty.RegisterAttached("MouseLeaveCommand", 
                typeof(ICommand), 
                typeof(MouseBehavior), 
                new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseLeaveCommandChanged))); 

     private static void MouseLeaveCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseLeave += new MouseEventHandler(element_MouseLeave); 
     } 

     static void element_MouseLeave(object sender, MouseEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseLeaveCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseLeaveCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseLeaveCommandProperty, value); 
     } 

     public static ICommand GetMouseLeaveCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseLeaveCommandProperty); 
     } 
     #endregion 

     #region MouseLeftButtonDown 

     public static readonly DependencyProperty MouseLeftButtonDownCommandProperty = 
      DependencyProperty.RegisterAttached("MouseLeftButtonDownCommand", 
               typeof(ICommand), 
               typeof(MouseBehavior), 
               new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseLeftButtonDownCommandChanged))); 

     private static void MouseLeftButtonDownCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseLeftButtonDown += element_MouseLeftButtonDown; 
     } 

     static void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseLeftButtonDownCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseLeftButtonDownCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseLeftButtonDownCommandProperty, value); 
     } 

     public static ICommand GetMouseLeftButtonDownCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseLeftButtonDownCommandProperty); 
     } 

     #endregion 

     #region MouseLeftButtonUp 

     public static readonly DependencyProperty MouseLeftButtonUpCommandProperty = 
      DependencyProperty.RegisterAttached("MouseLeftButtonUpCommand", typeof(ICommand), typeof(MouseBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseLeftButtonUpCommandChanged))); 

     private static void MouseLeftButtonUpCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseLeftButtonUp += element_MouseLeftButtonUp; 
     } 

     static void element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseLeftButtonUpCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseLeftButtonUpCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseLeftButtonUpCommandProperty, value); 
     } 

     public static ICommand GetMouseLeftButtonUpCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseLeftButtonUpCommandProperty); 
     } 

     #endregion 

     #region MouseMove 

     public static readonly DependencyProperty MouseMoveCommandProperty = 
      DependencyProperty.RegisterAttached("MouseMoveCommand", typeof(ICommand), typeof(MouseBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseMoveCommandChanged))); 

     private static void MouseMoveCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseMove += new MouseEventHandler(element_MouseMove); 
     } 

     static void element_MouseMove(object sender, MouseEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseMoveCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseMoveCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseMoveCommandProperty, value); 
     } 

     public static ICommand GetMouseMoveCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseMoveCommandProperty); 
     } 

     #endregion 

     #region MouseRightButtonDown 

     public static readonly DependencyProperty MouseRightButtonDownCommandProperty = 
      DependencyProperty.RegisterAttached("MouseRightButtonDownCommand", typeof(ICommand), typeof(MouseBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseRightButtonDownCommandChanged))); 

     private static void MouseRightButtonDownCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseRightButtonDown += element_MouseRightButtonDown; 
     } 

     static void element_MouseRightButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseRightButtonDownCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseRightButtonDownCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseRightButtonDownCommandProperty, value); 
     } 

     public static ICommand GetMouseRightButtonDownCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseRightButtonDownCommandProperty); 
     } 

     #endregion 

     #region MouseRightButtonUp 

     public static readonly DependencyProperty MouseRightButtonUpCommandProperty = 
      DependencyProperty.RegisterAttached("MouseRightButtonUpCommand", typeof(ICommand), typeof(MouseBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseRightButtonUpCommandChanged))); 

     private static void MouseRightButtonUpCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseRightButtonUp += element_MouseRightButtonUp; 
     } 

     static void element_MouseRightButtonUp(object sender, MouseButtonEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseRightButtonUpCommand(element); 

      command.Execute(e); 
     } 

     public static void SetMouseRightButtonUpCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseRightButtonUpCommandProperty, value); 
     } 

     public static ICommand GetMouseRightButtonUpCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseRightButtonUpCommandProperty); 
     } 

     #endregion 

     #region MouseWheel 

     public static readonly DependencyProperty MouseWheelCommandProperty = 
      DependencyProperty.RegisterAttached("MouseWheelCommand", typeof(ICommand), typeof(MouseBehavior), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseWheelCommandChanged))); 

     private static void MouseWheelCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)d; 

      element.MouseWheel += new MouseWheelEventHandler(element_MouseWheel); 
     } 

     static void element_MouseWheel(object sender, MouseWheelEventArgs e) 
     { 
      FrameworkElement element = (FrameworkElement)sender; 

      ICommand command = GetMouseWheelCommand(element); 



      command.Execute(e); 
     } 

     public static void SetMouseWheelCommand(UIElement element, ICommand value) 
     { 
      element.SetValue(MouseWheelCommandProperty, value); 
     } 

     public static ICommand GetMouseWheelCommand(UIElement element) 
     { 
      return (ICommand)element.GetValue(MouseWheelCommandProperty); 
     } 

     #endregion 

    } 
} 

和数据模板,不绑定行为

<DataTemplate x:Key="GamePieceTemplate"> 
      <Border MinWidth="10" MinHeight="10" Padding="0" BorderBrush="{StaticResource GridBorderBrush}" > 
       <Rectangle Style="{StaticResource GamePieceTrigger}" 
          StrokeThickness="1" 
          vw:MouseBehavior.MouseLeftButtonDownCommand="{Binding MouseLeftButtonDownCommand}" 
          vw:MouseBehavior.MouseLeftButtonUpCommand="{Binding MouseLeftButtonUpCommand}" 
          vw:MouseBehavior.MouseEnterCommand="{Binding MouseEnterCommand}" 
          vw:MouseBehavior.MouseLeaveCommand="{Binding MouseLeaveCommand}" 
          vw:MouseBehavior.MouseRightButtonUpCommand="{Binding MouseRightButtonUpCommand}"   
       /> 
      </Border> 
     </DataTemplate> 

然后这里是一个违规(Not Calling CanExecute)命令

#region MOUSE_LEFT_BUTTON_DOWN 
    private RelayCommand _mouseLeftButtonDownCommand; 
    public RelayCommand MouseLeftButtonDownCommand 
    { 
     get 
     { 
      if (_mouseLeftButtonDownCommand == null) 
      { 
       _mouseLeftButtonDownCommand = new RelayCommand(param => ExecuteMouseLeftButtonDown((MouseEventArgs)param), 
                   param => CanExecuteMouseLeftButtonDown(null)) 
       { 
        DisplayText = "MouseLeftButtonDownCommand", 
        Category = CATEGORY 
       }; 

      } 
      return _mouseLeftButtonDownCommand; 
     } 
     set { _mouseLeftButtonDownCommand = value; } 
    } 
    private bool CanExecuteMouseLeftButtonDown(object o) 
    { 
     return ((!this.IsPlayed) && !(this.value == GameConstants.PieceValues.FLAGGED)); 

    } 
    private void ExecuteMouseLeftButtonDown(MouseEventArgs e) 
    { 
     Debug.WriteLine("Mouse Down : " + e.GetPosition((IInputElement)e.Source)); 

     if (e.LeftButton == MouseButtonState.Pressed) 
     { 

      if (this.Value == GameConstants.PieceValues.BUTTON) 
      { 
       this.Value = GameConstants.PieceValues.PRESSED; 
       gameBoard.GameState = GameConstants.GameStates.IN_DECISION; 
      } 
      else 
       if (gameBoard.GameState != GameConstants.GameStates.WON && 
        gameBoard.GameState != GameConstants.GameStates.LOST) 
        gameBoard.GameState = GameConstants.GameStates.IN_PLAY; 


     } 

    } 
    #endregion 

代码和命令绑定我只是没有自动调用MouseExhaviors的CanExecute()。我确实在Execute方法中获得了我希望的调用。这可能是因为我目前正在做的事情,我只需要在我的Execute方法中调用CanExecute?是对的吗?如果是这样的话我想这可能会影响一个命令绑定的内容和方式,以使这个通话变得自动化。

回答

0

当您将ICommand绑定到MenuItemButton时,其CanExecute()方法将由WPF自动调用。这是因为how things are implemented in WPF

if (command.CanExecute(parameter)) 
{ 
    command.Execute(parameter); 
} 

由于Shape■不要本身支持的命令和您通过附加属性添加此功能,您应该以同样的方式实现它。

所以,解决的办法是:在你的事件处理程序,更换

command.Execute(e); 

if (command.CanExecute(e)) 
{ 
    command.Execute(e); 
} 
+0

是的是它的方式。谢谢。 –