有关WPF命令的问题

时间:2012-05-24 16:48:12

标签: c# wpf mvvm

我有一些关于WPF命令的问题。

  1. 我应该在哪里放置确认对话框?我应该在命令回调函数内显示它们吗?如果在应用程序的某些区域我不希望命令显示确认怎么办?

  2. 如果我有一个用户控件,显示可以删除的项目。该命令应该在应用程序的视图模型中,并且我将它用于项目删除,或者用户控件本身是否还有一个命令反过来调用视图模型的功能? (注意:应用程序视图模型是唯一具有执行此操作所需信息的模型)

  3. 如何在命令中传递数据?我主要使用DelegateCommand,并且在为网格项触发命令时,我想传递所选项,否则应用程序的主视图模型必须找到网格并找出其选择硬编码对网格的命令,而不是使其可重复使用。

3 个答案:

答案 0 :(得分:2)

这有点意见和风格。 。 。这是我的方法:

问题1:

我有一个处理任何确认的实用程序类,我使用MVVM Light中的轻量级消息来处理视图,确认和视图模型之间的通信。

编辑:关于第1点的更多信息

  

在我的命令中,我将发送一条消息   " ConfirmDeletionMessage",然后由我的对话框实用程序选取   类。对话框实用程序类显示相应的消息   用户,并检查结果。根据结果​​,它会   广播" DeletionConfirmedMessage"要么   " DeletionCanceledMessage,"然后由ViewModel处理   要么完成要么取消删除。

     

如果您有多个订阅者,则会涉及一些风险   消息,因为你不知道他们将要处理的订单,   但如果您对消息使用者有严格的管理,或确保   他们能够以随机顺序运行,这种方法有效   非常好,它将您的View和Model代码分开在一个testable中   方式。

问题2:

这是一个艰难的,它将取决于您的整体应用。我个人喜欢把它放在项目的视图模型中。这样,您就不必担心第三个问题了。相反,删除操作仅适用于您正在处理的项目。 但是,如果你必须处理列表项之外的数据(比如从列表中删除它),那么命令在父视图模型上更有意义。

问题3:

使用CommandParameter属性。你可以将它绑定到你想要的任何东西。

编辑回答#2

Mark Green(下面评论过的人)让我思考。我最初对WP7采用了这种方法,它绝对适合我需要做的事情。但是,还有其他方法可以解决这个问题。另一种选择是"确认类"可以由viewmodel使用。如果您使用的是IoC内核,那么使用构造函数/属性注入就可以轻松完成。或者,如果您有其他获取类的方法,请执行此操作,但这样做可以在测试中模拟出来。它可能看起来像这样:

public class ExampleViewmodel : ViewModel
{
      private IConfirmDialogManager _dialogManager;
      public ExampleViewmodel(IConfirmDialogManager dialog)
      {
            _dialogManager = dialog;
      }

      // ... code happens ...
      private void DeleteCommand()
      {
             bool result = _dialogManager.Confirm("Are you sure you want to delete?");
      }
}

使用IConfirmDialogManager接口,如下所示:

public interface IConfirmDialogManager
{
      bool Confirm(string message);
}

然后你将适当地实施。

答案 1 :(得分:2)

  

我应该在哪里放置确认对话框?我应该在命令回调函数内显示它们吗?如果在应用程序的某些区域我不希望命令显示确认怎么办?

确认对话框和显示消息对话框是视图。 您的VM应该有办法通知您的视图它想要显示或询问某些内容,然后视图应决定如何显示它(状态栏,窗口,弹出窗口,语音消息......)

  

如果我有一个用户控件,显示可以删除的项目。该命令应该在应用程序的视图模型中,并且我将它用于项目删除,或者用户控件本身是否还有一个命令反过来调用视图模型的功能? (注意:应用程序视图模型是唯一具有执行此操作所需信息的模型)

items控件应该引发删除命令。 VM应该处理命令并决定要做什么(VM应该具有所选项的列表,并且视图应该绑定到该列表)。

  

如何在命令中传递数据?我主要使用DelegateCommand,在触发网格项的命令时,我想传递所选项,否则应用程序的主视图模型必须找到网格并找出其选择,将命令硬编码到网格,而不是让它可重复使用。

命令可以有参数(例如RoutedUICommand)。命令绑定可以指定参数的绑定表达式。但是,正确的方法是将VM作为选择的来源,并在视图的选择和VM之间进行双向绑定。

答案 2 :(得分:1)

  1. 只需在viewmodel中使用dialogservice
  2. 即可
  3. 它取决于但是,使用RelativeSource绑定可以轻松到达命令所在的对象/视图模型
  4. CommandParameter是一种方式。事实上,您使用mvvm所需的所有信息都应绑定到您的viewmodel。因此,如果你有一个命令并且你需要listview中的selecteditem,你可以将它绑定到viewmodel而不需要将它设置为commandparameter