C# 关于WPF命令的问题

C# 关于WPF命令的问题,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一些关于WPF命令的问题 我应该在哪里放置确认对话框?我应该在命令回调函数中显示它们吗?如果在应用程序的某些区域,我不希望命令显示确认,该怎么办 如果我有一个显示可以删除的项目的用户控件。该命令应该在应用程序的视图模型中,我使用它来删除项,还是用户控件本身也应该有一个命令来调用视图模型的函数?(注意:应用程序视图模型是唯一具有执行此操作所需信息的模型) 如何在命令内传递数据?我主要使用的是DelegateCommand,在为网格项启动命令时,我希望传递所选项,否则应用程序的主视图模型将必须找

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

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

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

  • 如何在命令内传递数据?我主要使用的是
    DelegateCommand
    ,在为网格项启动命令时,我希望传递所选项,否则应用程序的主视图模型将必须找到网格并确定其选择,这将把命令硬编码到网格中,而不会使其可重用


  • 这是一点意见和风格。以下是我的方法:

    问题1:

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

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

    在我的命令范围内,我将按照 “ConfirmDeletionMessage”,然后由我的对话框实用程序拾取 班级。dialog实用程序类将显示相应的消息以 并检查结果。根据结果,它将 广播“DeletionConfirmedMessage”或 “DeletionCanceledMessage”,然后由ViewModel处理以 完成或取消删除

    如果您有多个订阅服务器,则会有一些风险 消息,因为你不知道他们要按什么顺序处理, 但是如果您对消息消费者有严格的管理,或者确保 由于它们能够以随机顺序运行,这种方法是有效的 很好,它以可测试的方式将视图和模型代码分开 时尚

    问题2:

    这是一个困难的问题,它将取决于您的整个应用程序。我个人喜欢把它放在项目的viewmodel中。这样,你就不必担心你的第三个问题了。相反,删除操作只对您正在处理的项目有效。但是,如果必须对列表项之外的数据执行操作(如从列表中删除),则将命令放在父viewmodel上更有意义

    问题3:

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

    编辑以回答#2

    马克·格林(他在下面评论)让我思考。我最初在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?");
          }
    }
    
    public interface IConfirmDialogManager
    {
          bool Confirm(string message);
    }
    
    具有如下所示的IConfirmDialogManager界面:

    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?");
          }
    }
    
    public interface IConfirmDialogManager
    {
          bool Confirm(string message);
    }
    

    然后您将适当地实施它。

    这其中有一点是观点和风格。以下是我的方法:

    问题1:

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

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

    在我的命令范围内,我将按照 “ConfirmDeletionMessage”,然后由我的对话框实用程序拾取 班级。dialog实用程序类将显示相应的消息以 并检查结果。根据结果,它将 广播“DeletionConfirmedMessage”或 “DeletionCanceledMessage”,然后由ViewModel处理以 完成或取消删除

    如果您有多个订阅服务器,则会有一些风险 消息,因为你不知道他们要按什么顺序处理, 但是如果您对消息消费者有严格的管理,或者确保 由于它们能够以随机顺序运行,这种方法是有效的 很好,它以可测试的方式将视图和模型代码分开 时尚

    问题2:

    这是一个困难的问题,它将取决于您的整个应用程序。我个人喜欢把它放在项目的viewmodel中。这样,你就不必担心你的第三个问题了。相反,删除操作只对您正在处理的项目有效。但是,如果必须对列表项之外的数据执行操作(如从列表中删除),则将命令放在父viewmodel上更有意义

    问题3:

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

    编辑以回答#2

    马克·格林(他在下面评论)让我思考。我最初在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?");
          }
    }
    
    public interface IConfirmDialogManager
    {
          bool Confirm(string message);
    }
    
    具有如下所示的IConfirmDialogManager界面:

    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?");
          }
    }
    
    public interface IConfirmDialogManager
    {
          bool Confirm(string message);
    }
    
    然后,您将适当地实施

    在哪里