有关 WPF 命令的问题

本文关键字:问题 命令 WPF 有关 | 更新日期: 2023-09-27 18:35:26

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

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

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

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

有关 WPF 命令的问题

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

问题1:

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

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

在我的命令中,我将发送一条消息,内容如下:"确认删除消息",然后由我的对话框实用程序拾取.class。 对话框实用程序类将相应的消息显示给用户,并检查结果。 根据结果,它将广播"删除确认消息"或"DeleteCanceledMessage",然后由 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);
}

然后,您将适当地实施。

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

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

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

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

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

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

  1. 只需在视图模型中使用对话服务
  2. 这取决于,但命令所在的对象/视图模型可以通过 RelativeSource 绑定轻松访问
  3. CommandParameter 是一种方式。 事实上,您使用 MVVM 您需要的所有信息都应该绑定到您的视图模型。 因此,如果您有一个命令并且需要列表视图中的选定项,则可以将其绑定到视图模型,而无需将其设置为命令参数