在使用mvvm方法的应用程序中,ViewModel提供一个或多个 Command -properties非常常见。这些属性通常具有 ICommand 或 DelegateCommand 等类型。
我不明白为什么我们在mvvm应用程序中需要这样的方法。提供公共方法并将视图中的操作直接绑定到此公共方法是不够的?
为什么ICommand存在?
答案 0 :(得分:8)
提供公共方法并绑定操作是不够的 从直接看到这个公共方法?为什么ICommand存在?
您无法绑定到xaml中的方法。你需要一个物体。因此,您需要将方法包装到对象中。
它是UI中的常见模式,某些操作始终不可用。在登录表单中,只有在输入用户名时,“登录”操作才可用。在MS Word中,仅当您选择某些内容时,“复制”或“剪切”操作才可用,否则按钮将被禁用且键盘快捷方式处于非活动状态
普通的事件处理程序不符合这些要求,但ICommand
服务器完全符合这些目的:
public interface ICommand
{
void Execute(object parameter);
bool CanExecute(object parameter);
event EventHandler CanExecuteChanged;
}
现在,让我们考虑复制和粘贴方案。使用ICommand标记可以如下所示:
<Button Content="Paste" Command="{Binding PasteCommand}" />
<MenuItem Header="Paste" Command="{Binding PasteCommand}" />
public ICommand PasteCommand {get;} = new DelegateCommand(Paste, () => Clipboard != null);
没有ICommand
会怎么样?为了简化,我们考虑一下,XAML允许绑定到方法:
<Button Content="Paste" Click="{Binding Paste}" IsEnabled="{Binding CanPaste}" />
<MenuItem Header="Paste" Click="{Binding Paste}" IsEnabled="{Binding CanPaste}"/>
public void Paste() {....}
private bool _canPaste;
public bool CanPaste
{
get { return _canPaste }
set
{
if (_canPaste != value)
{
_canPaste = value;
OnNotifyPropertyChanged(nameof(CanPaste);
}
}
}
正如您所看到的,它不仅更加冗长,而且还违反了DRY原则。每次要使用该命令时,都需要指定Paste
和CanPaste
绑定。如果您在没有CanPaste的情况下开始,之后又想添加它,该怎么办?然后,您必须在每次Paste
调用时添加CanPaste绑定。我向你保证,你会忘记它。
现在,如果你在WPF中这样做了:
<Button Content="Paste" Click="Call_ViewModel_Paste" />
//in codebehind:
void Call_ViewModel_Paste(oobject sender, RoutedEventArgs e)
{
ViewModel.Paste();
}
或最终:
<Button Content="Paste">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction MethodName="Paste" TargetObject="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
这两种方法都是正确的,它们遵循MVVM原则并且没有ICommand工作,但正如您所看到的,它们都不如ICommand
答案 1 :(得分:2)
提供公共方法并将视图中的操作直接绑定到此公共方法是否足够?
如果点击视图中的Button
,您将如何调用公共方法?
答案是您将Command
的{{1}}属性绑定到为您调用方法的视图模型的Button
属性。这是查看模型定义的任何操作使用命令公开的主要原因。
命令只是一个实现ICommand
接口的对象,并封装了要执行的操作的代码。
有关该概念的更多信息,请参阅以下链接。
https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/ https://msdn.microsoft.com/en-us/magazine/dn237302.aspx
答案 2 :(得分:1)
在MVVM中,你试图避免“代码隐藏”(这是MyView.cs文件中的代码),以避免View,ViewModel和Model的紧密耦合。
在MFC中,您刚刚注册了一个事件处理程序(在WPF中仍然可以),但在MVVM中,可以只绑定一个ICommand,而不是触发事件。
答案 3 :(得分:0)
简短:
例如纽扣
按钮通过创建由方法组成的事件(Click =“ XEvent”)起作用,然后我们告诉应用程序下一步该怎么做,即,调用其他明显与Code配合的方法。 (事件=>方法在MainWindow.xaml.cs
处生成。)
在MVVM中,我们避免模式背后的代码。要实现这一点,我们需要将DataContext设置为其他类(将充当中间件),例如说MainWindowViewModel.cs
。
通过实现ICommand接口和实现处理命令的方法,我们避免了维护MVVM模式的代码。
好吧,ICommand接口可以有其他选择,例如将ViewModel中的方法绑定到XAML中的命令(不过,首选) 这里
<Button Command="{ViewModel AnyMethodName}"/>
加 ICommand接口将为您提供CanExecute方法,该方法可用于启用/禁用控制器,简单的委托将不会为您提供该功能 希望这会有所帮助:)