I have a few questions regarding WPF commands.
-
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?
-
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)
-
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.
A bit of this is opinion and style . . . Here’s my approach:
Question 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.
Edit: A bit more information on point 1
Question 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.
Question 3:
Use the
CommandParameterproperty. You can bind this to whatever you want.EDIT to Answer #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. 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. 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:
With an IConfirmDialogManager interface that looks like this:
Which you would then implement appropriately.