Wpf PRISM DelegateCommand+;样本数据

Wpf PRISM DelegateCommand+;样本数据,wpf,xaml,prism,expression-blend,sample-data,Wpf,Xaml,Prism,Expression Blend,Sample Data,我有一个ViewModel,它使用DelegateCommand属性绑定到按钮的命令属性 <local:MyViewModel xmlns:local="clr-namespace:MyNamespace" xmlns:prism="http://www.codeplex.com/prism"> <local:MyViewModel.Age>47</local:MyViewModel.Age> <lo

我有一个ViewModel,它使用
DelegateCommand
属性绑定到
按钮的
命令
属性

<local:MyViewModel xmlns:local="clr-namespace:MyNamespace"
                   xmlns:prism="http://www.codeplex.com/prism">
    <local:MyViewModel.Age>47</local:MyViewModel.Age>
    <local:MyViewModel.PurchaseAlcohalCommand>
        <prism:DelegateCommand IsActive="True" />
    </local:MyViewModel.PurchaseAlcohalCommand>
</local:MyViewModel>
问题是我的示例数据不喜欢
DelegateCommand
对象。它抱怨:
类型“DelegateCommand”不包括任何可访问的构造函数。
此外,唯一公开的属性是
IsActive
属性

<local:MyViewModel xmlns:local="clr-namespace:MyNamespace"
                   xmlns:prism="http://www.codeplex.com/prism">
    <local:MyViewModel.Age>47</local:MyViewModel.Age>
    <local:MyViewModel.PurchaseAlcohalCommand>
        <prism:DelegateCommand IsActive="True" />
    </local:MyViewModel.PurchaseAlcohalCommand>
</local:MyViewModel>

47

更改视图模型以公开ICommand而不是DelegateCommand。DelegateCommand只是ICommand的一个实现;如果您以后想从MvvmLight切换到RelayCommand,您的视图和示例数据不必在意


我不确定这是否能解决你的问题,但我怀疑可能会。另外,这只是一个很好的编程实践。

您的
DelegateCommand
的设置方式,当它被激活时,它不会做任何事情。如果这是我们想要的行为,我的建议就是不要声明它。WPF将优雅地处理绑定到
null
ICommand
对象的问题

或者,如果需要将其绑定到实例化的DelegateCommand,可以将其子类化为
DelegateCommand
,以包含无参数构造函数

如果您希望它绑定到一个
DelegateCommand
,并且希望
DelegateCommand
在命令触发时实际执行某项操作,那么这将变得更加复杂。您必须使用我前面提到的子类
DelegateCommand
,但还必须能够在XAML中定义委托。我认为有一些例子,但我猜它们涉及到标记扩展之类的东西。您在这种方法中的投资回报可能有点低,但您的里程数可能会有所不同


最后一种选择是通常的处理方式:在ViewModel的构造函数中定义您的
DelegateCommand

我考虑将我的DelegateCommand设置为私有,并公开一个“包装器”属性以将该命令强制转换为ICommand,否则,我将无法进行调用,例如
purchasealcholcommand.raisecancecutechanged()
,因为它不是ICommand接口的一部分,而每次我想使用它时都会返回到DelegateCommand。哦,我从来没有计划使用RelayCommand,因为它依赖于CommandManager类。这是我公开命令的典型方式,我还没有看到示例数据中的这个问题。所以我想这取决于哪个问题更让你烦恼。通常,我会避免其他人实现ICommand,因为您发现了一个问题:很难告诉命令对象更新它的状态。遵循OO设计原则(特别是封装),命令本身应该知道何时应该更新——不需要告诉它更新。RelayCommand和Prism的DelegateCommand都是其他人的实现。RelayCommand只是欺骗并绑定到CommandManager.RequerySuggested事件以引发其CanExecuteChanged事件,而DelegateCommand公开了一个方法以显式引发事件。不过,我可能会走到中间,在维护原始属性的同时,通过附加属性将DelegateCommand作为ICommand公开。所以我只需要将一个属性包装为另一个属性,以ICommand的形式返回它
public ICommand MyCommand{get{return MyInternalCommand as ICommand;}}}
。。。Expression Blend认识到该命令在其生成的示例数据中仍然是DelegateCommand,这很有意义,因为您无法创建
ICommand
。我的示例数据仍然有效,但令人恼火的是,它没有连接到ICommand中,并使用示例数据启用/禁用按钮。哦,好吧。你是说如果我用MarkupExtension将DelegateCommand子类化,我就可以让设计时命令工作吗?也就是说,如果我的样本数据失败,CanExecute按钮将根据我的样本数据全部禁用?@m-y:是的,这在技术上是可能的。但是,在ViewModel的默认构造函数中定义相同的DelegateCommand将产生完全相同的结果,并且您不必弄清楚如何将所有这些内容硬塞进XAML中。只是一个友好的建议。我知道这已经向你建议过好几次了。这是有充分理由的。