WPF - 从UserControl引发命令时,CanExecute不会触发

时间:2009-07-16 10:12:03

标签: wpf user-controls mvvm wpf-controls command

我的大部分表单上都有一个按钮条usercontrol。

我添加了以下命令......

    public ICommand Create
    {
        get
        {
            return buttonCreate.Command;
        }
        set
        {
            buttonCreate.Command = value;
        }
    }

我已将它们设置为依赖项属性,以便我可以绑定它们......

        public static readonly DependencyProperty CreateCommandProperty =
        DependencyProperty.Register(
        "Create",
        typeof(ICommand),
        typeof(StandardButtonStrip),
        new PropertyMetadata((ICommand)null));

然后我将我的usercontrol绑定到命令...

<commoncontrols:StandardButtonStrip HorizontalAlignment="Stretch" Create="{Binding CreateCommand}" />

我正在设置命令如下......

_viewModel.CreateCommand = new DelegateCommand<object>(OnCreateCommand, CanCreate);

但是尽管事实上我总是在我的CanCreate方法上返回true,但按钮被禁用...如果我在返回时设置了断点,则它永远不会触发!

    public bool CanCreate(object parm)
    {
        return true;
    }

我试过这个看看它是否会刷新绑定,但没有快乐!

_viewModel.CreateCommand.RaiseCanExecuteChanged();

我认为问题在于用户控制以及我如何将Command作为属性传递,但不确定......

有人可以帮忙吗?

干杯,

安迪

3 个答案:

答案 0 :(得分:5)

这看起来的方式,你在视图模型上有一个依赖属性。如果你真的在使用MVVM,那绝对不是解决问题的方法(不是因为对模式的宗教信仰,而是因为它不是最佳方式)。

首先,您的视图模型是DependencyObject吗?

如果是,则应将其降级为实现INotifyPropertyChanged的类。为什么?因为Button的Command属性是DependencyProperty本身(继承自ButtonBase)并且已经支持数据绑定。

如果不是,那么它上面的依赖属性将不起作用,这很好,因为您首先不应该在视图模型上具有依赖项属性。

你应该做的是将视图模型作为控件的DataContext(我猜你已经有了这个设置)。然后将视图模型的CreateCommand更改为普通的ICommand,并像这样绑定createButton的Command属性(使用默认的StandardButtonStrip样式)

<Button Name="createButton" HorizontalAlignment="Stretch" Command="{Binding CreateCommand}" />

这样,它仍然是可重用的,您只需要确保与您的用户控件关联的任何视图模型都具有ICommand类型的属性CreateCommand(并且该视图模型将默认继承到按钮控件 - wpf家伙想到的最好的事情之一。)

所以回顾一下,你应该以相反的方式做,或多或少。

希望这很有帮助,欢呼。

答案 1 :(得分:1)

对接受的答案的一个警告 -

使用委托命令我只能在创建新的

时才能使用它

Command<T> : DelegateCommand<T>并连接命令管理器。

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

答案 2 :(得分:0)

您是否覆盖了任何用户控件的功能?

一个常见问题是在不调用base的实现的情况下覆盖方法。例如,如果您在未调用base.OnContentChanged()的情况下覆盖了OnContentChanged(),则可能会意外抑制ContentChanged事件的触发。