When working on large WPF or Silverlight applications, you can end up with a lot of XAML files. If you are using the MVVM pattern, many of those XAML files contain a View whose DataContext is expected to be set to a certain type of ViewModel object. It can sometimes become difficult to remember which Views expects which ViewModel as their DataContext. One very simple and lightweight way to help you and your team remember a View’s expected DataContext type is to leave an XML comment at the top of the XAML file. This incredibly simple and obvious technique can be a HUGE timesaver later on down the road!
I highly suggest that you get into the habit of doing this, if you haven’t done so already. You will thank yourself many times later…
I have found that when you have a one to one relationship between you views and view models it is pretty obvious what the data context is supposed to be. For example, if you have UsersView and UsersViewModel then clearly UsersViewModel is meant to be the DataContext of UsersView. But if UsersView uses a UserControl called MyUserControl which also expects UsersViewModel to be its DataContext, then having a comment like you suggest is very valuable.
We tend to use a naming convention such as:
Then we structure our solution so that the organization of View Models parallels the organization of Views. This allows us to know exactly what is connected to what and easily navigate between Views and View Models or vice versa.
Caliburn’s IViewStrategy uses naming conventions like this to automatically locate Views for View Models as well. We also have naming conventions for the scenario of multiple Views over the same ViewModel.
Best would be if MS added optional strong typing to WPF data binding.
Another option would be to add an mc:Ignorable attribute to allow the user to specify the data context type to the IDE (or to parse your type of comment); allowing features like “Find References” to work with bindings. I’ve been thinking about doing this for SharpDevelop 4.0; but we likely won’t have enough time.
Graeme: I agree that in many scenarios it’s obvious that XYZView uses an XYZViewModel. But I have also found that sometimes one VM is rendered by several Views, often they don’t know about each other. This precludes the option of using a class/file naming convention to clearly convey the relationship. For the sake of consistency across all Views, I opt to include the DataContext Comment in all XAML files.
Rob: I tend to use that pattern too. As I mentioned to Graeme above, sometimes a more complex UI doesn’t allow such one-to-one mappings via naming conventions.
Daniel: Interesting point about strong typing. I’m not holding my breath for that, though. 🙂 I bet that T4 templates could be used to achieve something similar to your second option.
[…] XAML Tip: DataContext Comment (Josh Smith) […]
@Daniel: actually MS seems to be going the opposite way, since they added binding support for .NET 4.0 dynamic objects 😉
Now where is the fun in that, I mean come on now.
[…] XAML Tip: DataContext Comment […]
XAML Tip: DataContext Comment…
DotNetBurner – burning hot .net content…
Thanks for taking the time to give us that practical little tip.
My pleasure, Nigel. 🙂
I also follow a naming convention similar to the one Rob mentioned but with a brief prefix descriptor.
For example, if I have a ViewModel called CustomerViewModel, all associated views follow the following convention:
*prefix*CustomerView, where ‘prefix’ describes something about the view. This could then be something like GridCustomerView, TabbedCustomerView, etc.
In any case, thanks for the tip Josh.
Josh, with all due respect, you’ve got the MVVM a little bit wrong. UserControl intended to be used by six-year-old children learning “programming”. MVVM suppose you write controls in a different way (this way is called Custom Control in VS). I mean that your control should have ControlTemplate and, if it provides some view, then it should have ContentTemplate as well.
Content-templates as you already should know possess DataType property which perfectly describes which type the DataContext is intended to be.
Something like that:
I also find it useful to use type-qualified property names when constructing your bindings’ PropertyPaths in Xaml. This adds some compile-time verification and also reveals the expected type of the DataContext.
I partly agree with archimed7592. First I dont think that Josh has MVVM wrong, I just think the standard way of doing MVVM (like the way josh does it) is wrong/flaky. From here I agree with archimed7592 that using WPF’s built in Templating you work around the flaky-ness of standard MVVM. I use datatemplating myself not control templating but the effect and code is essetianlly the same. However this just raises other problems ie. Designer support is reduced and you now also have to add the list of all of you templates to the appropriate resource dictionary. Cant wait to M$ solve this problem.