3

Hopefully this is a simple MVVM question, but I'm trying to grasp command parameters.

I have a user select an item from the ListBox, and click "Delete Selected". The ListBox binds SelectedItem to "SelectedTemplate". My button XAML looks like so:

<Button CommandParameter="{Binding SelectedTemplate}" Command="{Binding DeleteTemplateCommand}" Content="Delete Selected"/>

When i get to my execute command, I'm reading the parameter from the Command. However, I also can access "SelectedTemplate". If i use the passed parameter, I'd then have to convert it to the correct objecttype before removing the object, versus just going ahead and removing "selectedTemplate"

public void DeleteTemplate(object template)
{
    Convert.ChangeType(template, typeof(Template));
    if (template == SelectedTemplate )
    {
        _ESTContext.Templates.Remove(SelectedTemplate);
    }     
}

My question here is that to me it seems both satisfy the MVVM philosophy, is there a benefit/detriment to using one or the other?

chickenricekid
  • 390
  • 4
  • 19

3 Answers3

3

The only real difference is readability (and potentially one extra binding for the engine to have to evaluate, but that isn't going to really hurt you in this case).

You are using SelectedTemplate either way so I wouldn't bother with binding it to the parameter and use it directly.

Unless that is the only thing you are using SelectedTemplate for, in which case I would toss it as a variable, and bind directly to the selection:

<Button CommandParameter="{Binding ElementName=MyListBox, Path=SelectedItem}" Command="{Binding DeleteTemplateCommand}" Content="Delete Selected"/>
BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
2

The primary benefit of using a command parameter is that you can execute the same command against different inputs, as opposed to one hard-coded input. Being able to delete any item is arguably more flexible than being able to delete just SelectedTemplate. In practice, I tend to favor using parameters.

You can avoid the cast in your "execute" callback by using a generic command implementation (i.e., something like RelayCommand<TParameter>).

Mike Strobel
  • 25,075
  • 57
  • 69
  • Hmmm. that's a good point. However, i'd still have to go and GetType() the parameter in order to correctly delete it from the right Model, correct? – chickenricekid Aug 22 '14 at 17:35
  • A generic `RelayCommand` would accept callbacks with the expected parameter type (whatever the type of `T` is), and should cast the parameter to that type before invoking the callback. So, no, you would not need to do any conversions yourself. – Mike Strobel Aug 22 '14 at 17:39
  • I'll have to go and research how to implement a callback... Thanks – chickenricekid Aug 22 '14 at 18:03
  • Mike, I think i'm kind of lost on this now... I have public RelayCommand DeleteTemplateCommand { get { if (_deletetemplatecommand == null) { _deletetemplatecommand = new RelayCommand(DeleteTemplate, p=> true); } return _deletetemplatecommand; } } but it's still of the type "object". I'm deleting either a "Model" or a "Template" object - how do I set the command type to the correct object? – chickenricekid Aug 22 '14 at 18:59
  • Go back to your original implementation, replace the `RelayCommand` with a `RelayCommand – Mike Strobel Aug 22 '14 at 19:05
  • Maybe im just confused. I thought that i could replace RelayCommand – chickenricekid Aug 22 '14 at 19:09
  • Perhaps I misunderstood your problem. I thought you were trying to avoid casting an `object` to a `Template` in the handler. But if your command handler needs to handle *multiple argument types*, and delegate to different deletion methods based on the argument type, then my suggestion doesn't help. – Mike Strobel Aug 22 '14 at 19:14
  • Ah. Glad i clarified before i wasted too much time! Appreciate your help! – chickenricekid Aug 22 '14 at 19:16
1

My question here is that to me it seems both satisfy the MVVM philosophy, is there a benefit/detriment to using one or the other?

@MikeStrobel gave you a good argument for using parameters, so I guess you need someone arguing for using the VM property!

You are correct in that both satisfy MVVM, so really it just comes down to how you want your app to work.

In our apps that have this kind of functionality, our SelectedTemplate concept is key to how the UI works. There will be NullToVisibility/Booleanconverters bound to that property that dictate whether certain controls are enabled or visible. Detail sections, command buttons and all sorts of other workflow hang off whether you have selected a thing. With this workflow in mind, having a valid SelectedTemplate would make the DeleteTemplate button active. So for us it makes sense that our commands, such as DeleteTemplateCommand would all operate on the SelectedTemplate object. This means we don't need to pass command parameters around.

For us, performing operations (such as a delete) on something that isn't the SelectedTemplate doesn't make sense. For your app, and UI, it might.

Mashton
  • 6,037
  • 2
  • 25
  • 35