Search code examples
c#mvvmdata-bindinguwpicommand

MVVM ICommand Binding "higher up"


I'm working on a shopping-cart like application as a way to practice the MVVM design pattern.

I have a View whose ViewModel is pretty much just a ShoppingCart, and the ShoppingCart is primarily a list of Products.

Right now, my view shows the Products in a GridView, which uses a DataTemplate to show the Name , Price, and a Remove button for each Product. The thing is, due to databinding, if I try databinding the Command attribute of the Remove button to a RemoveCommand property in my ViewModel, the code fails because it looks for RemoveCommand in the Product class instead of the ViewModel class.

I highly doubt I want to break encapsulation and have the Product deal with removing itself from a ShoppingCart, but I can't seem to figure out the right way to tackle this issue.


Solution

  • Give your GridView a name and do a Command="{Binding ElementName=theGridView, Path=DataContext.RemoveCommand}". You can also use a RelativeSource binding, although I think the former is faster.

    You'll also want to pass the Product itself into the command handler so you know which one the user has clicked on, do that with CommandParameter="{Binding Path=.}". The RemoveCommand property should be declared to return type ICommand but should return a generic instance of RelayCommand i.e.:

    public ICommand RemoveCommand { get { return new RelayCommand<Product>(OnRemove); } }
    private void OnRemove(Product product)
    {
        // remove it here
    }