【问题标题】:Button command binding doesn't work按钮命令绑定不起作用
【发布时间】:2013-05-07 07:50:08
【问题描述】:

我创建了一个新的 UserContol,里面有一个按钮。我想像这样将按钮命令绑定到新用户控件的依赖属性。

<Grid>
 <Button Name="Button1" Command="{Binding Button1Command}" />
</Grid>

这是包含 UserControl 上的 DP:

public ICommand Button1Command
{
  get { return (ICommand)GetValue(Button1CommandProperty); }
  set { SetValue(Button1CommandProperty, value); }
}

public static readonly DependencyProperty Button1CommandProperty =
    DependencyProperty.Register("Button1Command", typeof(ICommand), typeof(BptCellTemplate), new FrameworkPropertyMetadata(null));

当我尝试使用它时,当我按下按钮时没有任何反应。它不识别命令。如果我添加一个事件,它会起作用。像这样:

 public static readonly DependencyProperty Button1CommandProperty =
    DependencyProperty.Register("Button1Command", typeof(ICommand), typeof(BptCellTemplate), new FrameworkPropertyMetadata(null, OnButton1CommandChanged));

private static void OnButton1CommandChanged(DependencyObject dependencyObject,
                                              DependencyPropertyChangedEventArgs args)
{
  var bptCellTemplate = dependencyObject as BptCellTemplate;
  if (bptCellTemplate == null || !(args.NewValue is ICommand))
  {
    return;
  }
  (bptCellTemplate.DataContext as BptCellTemplateViewModel).Button1Command = (ICommand)args.NewValue;

}

有没有办法在没有事件的情况下绑定它?因为它适用于我以相同方式执行的其他按钮属性(例如Visibility

【问题讨论】:

  • 你在哪里设置 Button1Command 的值?

标签: c# .net wpf


【解决方案1】:

您的绑定可能不起作用,因为没有任何内容表明 Button1Command 属性是您的 UserControl 的成员。

在 Visual Studio 中调试程序时,您可以通过查看“输出”窗口来确认这是问题所在。您可能会看到未找到成员 Button1Command 的绑定错误。

解决此问题的典型方法是为您的UserControl 的根元素添加一个名称属性,例如x:Name="root"(您可以选择自己的名称或使用现有名称(如果有的话)。然后,将您的绑定更改为引用新名称的命令:

<Button Name="Button1" Command="{Binding Button1Command, ElementName=root}" />

【讨论】:

    【解决方案2】:
    1. 你需要类实现 ICommand 接口。

      public class RelayCommand : ICommand
      {
          #region Fields
      
          readonly Action<object> _execute;
          readonly Predicate<object> _canExecute;
      
          #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)
          {
              if (execute == null)
                  throw new ArgumentNullException("execute");
      
              _execute = execute;
              _canExecute = canExecute;
          }
      
          #endregion // Constructors
      
          #region ICommand Members
      
          [DebuggerStepThrough]
          public bool CanExecute(object parameter)
          {
              return _canExecute == null ? true : _canExecute(parameter);
          }
      
          public event EventHandler CanExecuteChanged
          {
              add { CommandManager.RequerySuggested += value; }
              remove { CommandManager.RequerySuggested -= value; }
          }
      
          public void Execute(object parameter)
          {
              _execute(parameter);
          }
      
          #endregion // ICommand Members
      }
      
    2. 现在绑定很简单。 在 DataContext 中定义命令(MVVM ...等) 不记得设置 DataContext ... 例如 DataContext = this; (这是你的窗口)

      RelayCommand _btnCommand;
      public ICommand Button1Command
      {
          get
          {
              if (_btnCommand == null)
              {
                  _btnCommand = new RelayCommand(param => this.ExecuteButton1(),
                      param => this.CanButton1());
              }
              return _btnCommand;
          }
      }
      
      public void ExecuteButton1()
      {
      }
      
      public bool CanButton1()
      {
          return true;
      }
      

    就是这样……

    【讨论】:

    • 值得注意的是,在大多数情况下,您可以简单地使用RoutedCommand:您不需要创建自己的ICommand 类。
    猜你喜欢
    • 1970-01-01
    • 2015-12-09
    • 2020-03-06
    • 1970-01-01
    • 2018-07-31
    • 2019-05-20
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    相关资源
    最近更新 更多