2013-05-07 83 views
2

我用一个按钮创建了一个新的UserContol。我想将按钮命令绑定到新用户控件的依赖属性。按钮命令绑定不起作用

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

这是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例如)的作品

+1

您在哪里设置了Button1Command的值? – jure 2013-05-07 08:19:49

回答

1
  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; 
    } 
    

就是这样......

+0

Darkzaleus:感谢编辑:) – misak 2013-05-07 08:36:29

+2

值得注意的是,在大多数情况下,您可以简单地使用'RoutedCommand':您不需要创建自己的'ICommand'类。 – 2013-05-07 09:01:47

2

这有可能是你的约束力不工作,因为没有什么说的Button1Command属性是你UserControl的成员。

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

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

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