One of the more common problems (or rather: challenges :)) you’ll run in to when working with the MVVM design pattern is binding from a DataTemplate of an ItemsControl to a command defined on your ViewModel. For example: you might have a ListBox filled with items, and you want a button in every ListBox item which, on click, should execute a command (delete the item, for example).
When you look around the internet, you’ll find a few possible solutions to this problem. One “easy” one is to simply define a command in each item of the collection you’re binding the ListBox to: as each ListBox item’s DataContext is exactly one item, each DataContext contains a command, so you can bind to it. Needless to say, this is not the way to go (do you really want a separate command, or a reference to a common command, in each ListBox item?).
Another common solution (and a much better one) is using RelativeSource bindings. You can find a few posts on that on the Silverlight forum and on CodeProject. As you might notice while looking for info on that: it used to be a WPF-only feature, but it is now supported in Silverlight. You can find the MSDN page on it here.
While that works, there’s actually a much, much easier solution: Element Binding.
Take this piece of code:
This is from a project I’m currently working on: the MenuViewModel defines a command, ShowView, which accepts a parameter (the Uri a button click should navigate to). The menu consists of a (variable, depending on the profile of who logs in) list of buttons, which is created by binding a list of MenuItems to an ItemsControl defined on the View.
So, how do you get the button click event bound to the command defined on your ViewModel? All my views have a root Grid, LayoutRoot. As the Views’ DataContext is the ViewModel, the DataContext of LayoutRoot is that same ViewModel – which contains the defined command. Through element binding, I can now easily bind the command to my ListBox Item, as you can see in the provided code example.
I can’t share the complete code this time (that would require sharing most of the internal libraries for MVVM etc we’re using, and would probably violate numerous NDA’s/intellectual property rights :)), but I hope the code sample I provided helps some of you out.
Happy coding! 🙂