12

I'm trying to work out the best way to couple my Views and ViewModels in MVVM and I've settled on the ViewModel-first approach using typed DataTemplates, as described in this article and in this answer. I'm using Prism and have multiple modules which have their own projects/class libraries.

My question is: Where should my DataTemplates live in my solution?

  1. Should I put the DataTemplates in a Resource Dictionary which lives in the same project that has the types/ViewModels it renders?
  2. Should I put the DataTemplates in a Resource Dictionary which lives in the project which has the application's MainWindow (i.e. Shell.xaml)?
  3. Should these Resource Dictionaries then be added to App.Current.MainWindow.Resources.MergedDictionaries?

I hope this is enough information to describe what I'm trying to do.

Update: see comments of selected answer.

Community
  • 1
  • 1
Blake Mumford
  • 17,201
  • 12
  • 49
  • 67

3 Answers3

2

Updated to explain more clear.

I will say if your DataTemplate is generic: i.e You have a UserControl that binds to a ViewModel, and that ViewModel has BaseViewModel, which expose some sort of properties. Your DataTemplate is displaying those properties. So you can use this DataTemplate on every ViewModel that Implement the BaseViewModel.

Is better to put it in App.xaml, so you will able to pull it out with the Key and apply on different place in your project.

But if your DataTemplate is very specific,

i.e There is a UserControl that only binds on the specified property in that ViewModel and you know no other control will binds to that ViewModel, you will want to put into the same Xaml file's Resources or where you define your UserControl.

King Chan
  • 4,212
  • 10
  • 46
  • 78
  • I understand that I can use `DataTemplates` to customise the display of data in say, a `ListBox` and I can re-use this `DataTemplate` and apply it to multiple `ListBoxes` by referring to its `x:Key`. But according to Josh Smith's article (see above), I believe I can also use **typed** `DataTemplates` to couple a View/UserControl to a `ViewModel`. I.e. if I add a ViewModel object to a `ListBox`, WPF will render the ViewModel using the UserControl specified in the `DataTemplate` (instead of using ToString()). Am I way off here? – Blake Mumford Mar 04 '12 at 04:48
  • @Angavar Yes, you can also use typed DataTemplate to applies it. I am just giving an example like how you can use their x:Key pull out the Template, Style etc. – King Chan Mar 04 '12 at 18:18
2

I'm sure that the best way here is to use Themes\Generic.xaml resources file. This is file (it should be exactly in folder Themes and has name exactly Generic.xaml) used by WPF/Silverlight themes engine and contains resources shared through whole application. You can also create separate file in folder Themes with name like Generic.DataTemplates.xaml and add link to it from Generic.xaml. Google knows a lot about generic.xaml or you can see more details in my answer here: WPF Prism - Where to put Resources?

Community
  • 1
  • 1
chopikadze
  • 4,219
  • 26
  • 30
  • Hey, thanks for your suggestion. I read that post some time ago and I use the method Rachel describes there. I have an Infrastructure project with a Themes folder where I store my styles in `Resource Dictionaries`. The problem is that this Infrastructure project is referenced by all my other projects/modules. In order to use typed `DataTemplates` I'll require references to the projects that contain my ViewModels which would mean creating a circular dependency. Should I create a separate project to hold only `DataTemplates`? – Blake Mumford Mar 04 '12 at 08:30
  • 1
    I think you can create just folder Themes in your module's assembly. I do this way in current project - I have shared templates in separate UI assembly and almost each module's assembly has it's own Themes folder – chopikadze Mar 04 '12 at 09:15
  • Ok, that sounds like the way to go! Thanks, I appreciate your advice. I'll see if I can get it working. – Blake Mumford Mar 04 '12 at 09:26
  • Great! I took your advice and this is working nicely. I defined the `DataTemplates` in the module assembly as a Resource Dictionary and then added that Resource Dictionary to a Merged Resource Dictionary in `App.Current.MainWindow.Resources.MergedDictionaries`. Thanks for your time :) – Blake Mumford Mar 05 '12 at 05:23
0

According to Microsofts App Studio the DataTemplates should live in a DataTemplates Subdirectory under the Views Directory. A Universal app has this directory for both the Windows UI as for the Windows Phone UI so its not in the Shared project because they are not the Same. Don't use the Converge PRISM architecture. Its completely wrong designed! That was not written with a Windows and a Windows Phone architecture in mind but like they call it Converged. It should have been completely redesigned like it works in Microsofts App Studio. Don't look for Dependency Injection its not in it and not needed. Most use Dependency Injection for stub or fake interfaces. The DataContext for design data works now so good with json data that a Dependency Injection component would be overkill.