简体   繁体   English

有关WPF命令的问题

[英]Questions regarding WPF commands

I have a few questions regarding WPF commands. 我对WPF命令有一些疑问。

  1. Where should I put confirmation dialogs? 我应该在哪里放置确认对话框? Should I show them right inside the command callback function? 我应该在命令回调函数中显示它们吗? What if in some areas in the application I don't want a command to show a confirmation? 如果在应用程序的某些区域中我不希望命令显示确认怎么办?

  2. If I have a user control that shows items that can be deleted. 如果我有一个显示可以删除的项目的用户控件。 Should the command be in the application's view model, and I use it for the item deletion, or should the user control itself also have a command that in turn calls the view model's function? 该命令应该在应用程序的视图模型中,还是将其用于项目删除,还是用户控件本身也应具有一个依次调用视图模型功能的命令? (Note: the application view model is the only one having the information needed to do this operation) (注意:应用程序视图模型是唯一具有执行此操作所需信息的模型)

  3. How can I pass data within a command? 如何在命令中传递数据? I am using mostly DelegateCommand , and upon firing a command for a grid item, I'd like to pass the selected item, otherwise the application's main view model would have to find the grid and figure out its selection which will hardcode the command to the grid and not make it reusable. 我主要使用DelegateCommand ,并在为网格项触发命令时,我想传递选定的项,否则应用程序的主视图模型将必须找到网格并找出其选择,这会将命令硬编码到网格并使其不可重用。

A bit of this is opinion and style . 这有点意见和风格。 . . Here's my approach: 这是我的方法:

Question 1: 问题1:

I have a utility class that handles any confirmation, and I use the lightweight messaging in MVVM Light to handle communication between the view, the confirmation, and the viewmodel. 我有一个处理任何确认的实用程序类,并且在MVVM Light中使用轻量级消息传递来处理视图,确认和viewmodel之间的通信。

Edit: A bit more information on point 1 编辑:关于点1的更多信息

From within my Command, I will send a message along the lines of "ConfirmDeletionMessage", which is then picked up by my dialog utility class. 在我的Command中,我将沿着“ ConfirmDeletionMessage”行发送一条消息,然后由我的对话框实用程序类接收该消息。 The dialog utility class displays the appropriate message to the user, and checks the results. 对话框实用程序类向用户显示适当的消息,并检查结果。 Based on the results, it will either broadcast a "DeletionConfirmedMessage" or "DeletionCanceledMessage," which is then handled by the ViewModel to either complete or cancel the delete. 根据结果​​,它将广播“ DeletionConfirmedMessage”或“ DeletionCanceledMessage”,然后由ViewModel处理,以完成或取消删除。

There is some risk involved if you have multiple subscribers to this message, as you won't know what order they're going to be handled, but if you have strict management on message consumers, or ensure that they are able to run in a random order, this approach works pretty well, and it separates your View and Model code in a testable fashion. 如果您有多个订阅者,则存在一定的风险,因为您不知道将按照什么顺序处理消息,但是如果您对消息使用者有严格的管理,或者确保他们可以在消息使用者中运行随机顺序,这种方法效果很好,并且以可测试的方式将您的View和Model代码分开。

Question 2: 问题2:

This is a tough one, and it is going to depend on your overall application. 这是一个艰难的过程,它将取决于您的整体应用程序。 I'm personally a fan of putting it in the item's viewmodel. 我个人是将其放入项目的视图模型的爱好者。 That way, you don't have to worry about your third question as much. 这样,您不必担心第三个问题。 Instead, the delete action simply works on the item you're dealing with. 相反,删除操作仅适用于您要处理的项目。 However , if you have to act on data outside of your list item (like removing it from the list), it makes more sense for the command to be on the parent viewmodel. 但是 ,如果您必须对列表项之外的数据进行操作(例如将其从列表中删除),则将命令放在父viewmodel上更为有意义。

Question 3: 问题3:

Use the CommandParameter property. 使用CommandParameter属性。 You can bind this to whatever you want. 您可以将此绑定到您想要的任何对象。

EDIT to Answer #2 编辑答案#2

Mark Green (who commented below) got me thinking. 马克·格林(马​​克·格林(以下评论))让我思考。 I originally adopted this approach for WP7, and it absolutely suited what I needed to do. 我最初在WP7中采用了这种方法,它绝对适合我需要做的事情。 However, there are other ways of handling this that should absolutely be considered. 但是,还有其他处理方法应该绝对考虑。 Another option is a "confirmation class" that can be used by your viewmodel. 另一个选项是您的视图模型可以使用的“确认类”。 If you are using an IoC kernel, this becomes easy to do with constructor / property injection. 如果您使用的是IoC内核,那么通过构造函数/属性注入就可以轻松实现。 Alternatively, if you have other methods of getting the class, do so, but do it in a way that you can mock out in testing. 或者,如果您还有其他获取类的方法,请这样做,但要以可以在测试中模拟的方式进行。 It might look something like this: 它可能看起来像这样:

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?");
      }
}

With an IConfirmDialogManager interface that looks like this: 使用IConfirmDialogManager接口,如下所示:

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

Which you would then implement appropriately. 然后您将适当实施。

Where should I put confirmation dialogs? 我应该在哪里放置确认对话框? Should I show them right inside the command callback function? 我应该在命令回调函数中显示它们吗? What if in some areas in the application I don't want a command to show a confirmation? 如果在应用程序的某些区域中我不希望命令显示确认怎么办?

Confirmation dialogs and show message dialogs are views. 确认对话框和显示消息对话框是视图。 Your VM should have a way of notifying your view that it wants to display something or ask something, then the view should decide how to display it (status bar, window, pop-up, voice message, ...) 您的VM应该有一种通知您的视图的方式,即它想要显示或询问某些内容,然后该视图应决定如何显示它(状态栏,窗口,弹出窗口,语音消息等)。

If I have a user control that shows items that can be deleted. 如果我有一个显示可以删除的项目的用户控件。 Should the command be in the application's view model, and I use it for the item deletion, or should the user control itself also have a command that in turn calls the view model's function? 该命令应该在应用程序的视图模型中,还是将其用于项目删除,还是用户控件本身也应具有一个依次调用视图模型功能的命令? (Note: the application view model is the only one having the information needed to do this operation) (注意:应用程序视图模型是唯一具有执行此操作所需信息的模型)

The items control should raise a delete command. 项目控件应引发一个删除命令。 The VM should handle the command and decide what to do (the VM should have the list of the selected items and the view should be binding to that list). VM应该处理命令并决定要执行的操作(VM应该具有所选项目的列表,并且视图应绑定到该列表)。

How can I pass data within a command? 如何在命令中传递数据? I am using mostly DelegateCommand, and upon firing a command for a grid item, I'd like to pass the selected item, otherwise the application's main view model would have to find the grid and figure out its selection which will hardcode the command to the grid and not make it reusable. 我主要使用DelegateCommand,并且在为网格项目触发命令后,我想传递选定的项目,否则应用程序的主视图模型将必须找到网格并找出其选择,这会将命令硬编码到网格并使其不可重用。

Commands can have parameters (eg RoutedUICommand). 命令可以具有参数(例如RoutedUICommand)。 The command binding can specify a binding expression for the parameter. 命令绑定可以为参数指定绑定表达式。 However, the correct approach is for the VM to be the source of the selection with a two way binding between the view's selection and the VM's. 但是,正确的方法是让VM成为选择的源,并在视图的选择和VM之间进行双向绑定。

  1. simply use a dialogservice in your viewmodel 只需在您的视图模型中使用一个dialogservice
  2. it depends but nevertheless the object/viewmodel where the command is located can easily reached with RelativeSource binding 它取决于但仍然可以通过RelativeSource绑定轻松到达命令所在的对象/视图模型
  3. CommandParameter is one way. CommandParameter是一种方法。 in fact you use mvvm all information you need should be bind to your viewmodel. 实际上,您使用mvvm应该将所需的所有信息绑定到您的viewmodel。 so if you have a command and you need the selecteditem from a listview, you can bind it to the viewmodel and dont need to set this as commandparameter 因此,如果您有命令,并且需要列表视图中的selecteditem,则可以将其绑定到视图模型,而无需将其设置为commandparameter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM