1

我有几个关于 WPF 命令的问题。

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

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

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

4

3 回答 3

2

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

问题一:

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

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

在我的命令中,我将按照“ConfirmDeletionMessage”的行发送一条消息,然后由我的对话实用程序类接收。对话实用程序类向用户显示适当的消息,并检查结果。根据结果​​,它将广播“DeletionConfirmedMessage”或“DeletionCanceledMessage”,然后由 ViewModel 处理以完成或取消删除。

如果您有多个订阅者订阅此消息,则会涉及一些风险,因为您不知道他们将被处理的顺序,但是如果您对消息消费者进行严格管理,或者确保他们能够在一个随机顺序,这种方法工作得很好,它以可测试的方式分离你的视图和模型代码。

问题2:

这是一项艰巨的任务,它将取决于您的整体应用程序。我个人很喜欢将它放在项目的视图模型中。这样,您就不必担心第三个问题。相反,删除操作仅适用于您正在处理的项目。 但是,如果您必须对列表项之外的数据进行操作(例如将其从列表中删除),则将命令放在父视图模型上会更有意义。

问题 3:

使用该CommandParameter物业。你可以把它绑定到你想要的任何东西上。

编辑答案#2

马克格林(他在下面评论)让我思考。我最初对 WP7 采用了这种方法,它绝对适合我需要做的事情。但是,绝对应该考虑其他处理此问题的方法。另一个选项是您的视图模型可以使用的“确认类”。如果您使用的是 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);
}

然后您将适当地实施。

于 2012-05-24T16:59:37.543 回答
2

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

确认对话框和显示消息对话框是视图。你的虚拟机应该有一种方法来通知你的视图它想要显示一些东西或询问一些东西,然后视图应该决定如何显示它(状态栏、窗口、弹出窗口、语音消息......)

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

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

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

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

于 2012-05-24T17:26:33.723 回答
1
  1. 只需在视图模型中使用对话服务
  2. 它取决于,但命令所在的对象/视图模型可以通过 RelativeSource 绑定轻松访问
  3. CommandParameter 是一种方式。实际上,您使用 mvvm 需要的所有信息都应该绑定到您的视图模型。因此,如果您有命令并且需要列表视图中的选定项,则可以将其绑定到视图模型,而无需将其设置为命令参数
于 2012-05-25T10:32:36.907 回答