use*_*799 75 command mvvm relaycommand routedcommand
什么是之间的差异的RoutedCommand和RelayCommand?何时使用RoutedCommand以及何时在MVVM模式中使用RelayCommand?
wek*_*mpf 68
的RoutedCommand是WPF的一部分,而RelayCommand用WPF弟子,约什史密斯创建).
但严重的是,RS Conley描述了一些不同之处.关键区别在于RoutedCommand是一个ICommand实现,它使用RoutedEvent来路由树,直到找到命令的CommandBinding,而RelayCommand不进行路由,而是直接执行某个委托.在MV-VM场景中,RelayCommand(Prism中的DelegateCommand)可能是更好的选择.
Mar*_*arc 34
关于在MVVM中使用RelayCommand和RoutedCommand,我的主要区别如下:
代码的位置
RelayCommand允许您在任何类中实现该命令(如带有委托的ICommand属性),然后通常将数据绑定到控件,该控件将调用该命令.这个类是ViewModel.如果使用routed命令,则必须在控件的代码隐藏中实现与命令相关的方法,因为这些方法由CommandBinding-element的属性指定.假设严格的MVVM意味着具有"空"代码隐藏文件,实际上不可能在MVVM中使用标准路由命令.
什么RS康利说,那RelayCommand允许您定义视图模型外RelayCommand是正确的,但首先它允许你定义它里面的视图模型,它的RoutedCommand没有.
路由
另一方面,只要您的接口基于单个viewModel,RelayCommands就不支持通过树进行路由(如前所述),这不是问题.如果不是,例如,如果您有一个具有自己的viewModel的项目集合,并且想要立即为父元素中的每个项目调用子ViewModel的命令,则必须使用路由(另请参阅CompositeCommands) .
总而言之,我会说,标准的RoutedCommands在严格的MVVM中不可用.RelayCommands非常适合MVVM,但不支持您可能需要的路由.
RS *_*ley 22
不同之处在于RelayCommand可以接受委托.您可以在ViewModel之外定义RelayCommand.然后,ViewModel可以在创建命令时将委托添加到命令,并将命令绑定到UI对象(如控件).反过来,委托可以访问ViewModel的私有变量,因为它们是在View Model本身的范围内定义的.
它用于减少ViewModel中包含的代码量,因为趋势是将Routed命令定义为ViewModel中的嵌套类.两者的功能在其他方面类似.
小智 15
我认为RoutedCommands在严格的MVVM中是完全合法的.虽然RelayCommands通常因其简单性而优选,但RoutedCommands有时会提供组织优势.例如,您可能需要几个不同的视图来连接到共享的ICommand实例,而不直接将该命令暴露给底层的ViewModel.
作为旁注,请记住严格的MVVM并不禁止使用代码隐藏.如果这是真的那么你永远不能在你的视图中定义自定义依赖属性!
要在严格的MVVM框架内使用RoutedCommand,您可以按照以下步骤操作:
为自定义命令声明静态RoutedCommand实例.如果计划使用ApplicationCommands类中的预定义命令,则可以跳过此步骤.例如:
public static class MyCommands {
public static RoutedCommand MyCustomCommand = new RoutedCommand();
}
Run Code Online (Sandbox Code Playgroud)使用XAML将所需视图附加到RoutedCommand:
<Button Command="{x:Static local:MyCommands.MyCustomCommand}" />
Run Code Online (Sandbox Code Playgroud)您的一个视图绑定到合适的ViewModel(即任何ViewModel实现命令功能)需要公开一个自定义DependencyProperty,它将绑定到您的ViewModel的实现:
public partial class MainView : UserControl
{
public static readonly DependencyProperty MyCustomCommandProperty =
DependencyProperty.Register("MyCustomCommand",
typeof(ICommand), typeof(MainView), new UIPropertyMetadata(null));
public ICommand MyCustomCommand {
get { return (ICommand)GetValue(MyCustomCommandProperty); }
set { SetValue(MyCustomCommandProperty, value); }
}
Run Code Online (Sandbox Code Playgroud)相同的视图应该从步骤1绑定到RoutedCommand.在XAML中:
<UserControl.CommandBindings>
<CommandBinding Command="{x:Static local:MyCommands.MyCustomCommand}"
CanExecute="MyCustomCommand_CanExecute"
Executed="MyCustomCommand_Executed"
/>
</UserControl.CommandBindings>
Run Code Online (Sandbox Code Playgroud)
在视图的代码隐藏中,关联的事件处理程序将从步骤3中声明的依赖项属性委托给ICommand:
private void MyCustomCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
var command = this.MyCustomCommand;
if (command != null) {
e.Handled = true;
e.CanExecute = command.CanExecute(e.Parameter);
}
}
private void MyCustomCommand_Executed(object sender, ExecutedRoutedEventArgs e) {
var command = this.MyCustomCommand;
if (command != null) {
e.Handled = true;
command.Execute(e.Parameter);
}
}
Run Code Online (Sandbox Code Playgroud)最后,将ViewModel的命令实现(应该是ICommand)绑定到XAML中的自定义依赖项属性:
<local:MainView DataContext="{Binding MainViewModel}"
MyCustomCommand="{Binding CustomCommand}" />
Run Code Online (Sandbox Code Playgroud)这种方法的优点是你的ViewModel只需要提供ICommand接口的单个实现(它甚至可以是一个RelayCommand),而任意数量的视图都可以通过RoutedCommand附加到它,而不需要直接绑定到它视图模型.
不幸的是,ICommand.CanExecuteChanged事件无法正常工作.当ViewModel希望View刷新CanExecute属性时,您必须调用CommandManager.InvalidateRequerySuggested().
| 归档时间: |
|
| 查看次数: |
50984 次 |
| 最近记录: |