Should I be using UserControls for my Views instead of DataTemplates?
Asked Answered
D

3

12

I was reading this post and the author makes the suggestion that using DataTemplates to define a ViewModel is a lunatic's way to do it (#7). I do that all the time, is it really that bad?

<DataTemplate DataType="{x:Type local:MyViewModel}">
    <Grid>
        ...
    </Grid>
</DataTemplate>

Most of my Views are simply a ResourceDictionary that defines a DataTemplate or two. To me, it makes much better sense to do this than creating a UserControl for every ViewModel. Why would I want the extra layer in WPF's visual tree when it's not needed? And why would I want to take care of mapping ViewModels to Views when a DataTemplate does that for me? Is this syntax really a "lunatics approach"?

Dorsett answered 26/5, 2011 at 11:50 Comment(2)
I work in Visual Studio, and as far as I know, you can't get designer support for DataTemplates. For non-trivial views, I like seeing how it looks while I modify the XAML. But I don't know about how it works in Blend.Beheld
@Beheld That is true, I had forgotten that. I almost never use VS's XAML Designer since its laggy, slow, and doesn't work half the time. In the event I do want to use it to design a DataTemplate, I usually create a new UserControl, design it the way I want it, then copy/paste the contents into a DataTemplate.Dorsett
W
7

Nothing bad about it, except for incredibly large xaml files and the lack of edit support that DataTemplates have on the design surface.

If those issues are hurting you, you can always...

<DataTemplate DataType="{x:Type local:MyViewModel}">
    <local:MyViewModelUserControl />
</DataTemplate>
Werra answered 26/5, 2011 at 14:12 Comment(3)
As I mentioned in response to Souvik's post, I usually create a separate ResourceDictionary per View, and merge them all at runtime. This makes my xaml files a reasonable size. The lack of editing support from the designer I can understand, although I hate that thing and almost never use it (I had actually forgotten about it when I posted the question). I find it much faster to code without it.Dorsett
I also used the solution suggested by Will. I found it an elegant solution. When you have complex screen cinametic, your can break it down in multiple sub views/viewmodels, and you keep benefit of the visual designer of course, because each part of the whole view are just other smaller views.Bouffard
@Rachel: It does have its (granted, limited) benefits. Specifically when trying to get everything lined up correctly. I always seem to have an Expander in my data template that I can't simply click on in order to expose its contents for design work...Werra
P
1

The good thing with DataTemplate is that they are strongly typed to Viewmodel classes. All you need to do is create a ContentPresenter in View and Bind DataContext to VM. If your DataTemplate is defined in a ResourceDictionary and has a DataType attribute instead of Key, WPF will internally figure out the right DataTemplate for the VM class and display it.

But as you mentioned, we cannot create the DataTemplate in a seperate file. So the file where the DataTemplates exist in ResourceDictionary (e.g. App.xaml), the file gets really messy and it becomes difficult to manage the code soon.

So my take is, if the VM is simple create a DataTemplate. Or else it is always better to create a seperate UserControl and bind its content to the VM.

Playacting answered 26/5, 2011 at 12:28 Comment(3)
Actually the DataTemplates each have their own .xaml file, and those files get added to App.Current.MainWindow.Resources.MergedDictionaries at runtime. This keeps the ResourceDictionary files small and easy to manage.Dorsett
Ok, I never tried putting DataTemplates in seperate file. That should take care of keeping ResourceDictionary files clean. One more problem I faced was that not all controls support ICommand which can be bound to VM. e.g. If I had to handle MouseDown on TextBlock, I create an event handler in code behind of the UserControl and then call appropriate Command in VM from there. Is there a cleaner way to call Commands in VM from DataTemplate?Playacting
I use the code found here: marlongrech.wordpress.com/2008/12/04/… It allows you to attach a command to any event such as MouseDown or SelectionChanged. Also, if you give your ResourceDictionary an x:Class attribute and add a new class that is named the same as your ResourceDictionary with a .cs extension (MyResourceDictionary.xaml.cs) it will create a code-behind file for it.Dorsett
C
0

I run into the issue with performance. There is difference between next two case:

1.

<DataTemplate DataType="{x:Type local:MyViewModel}">
    <!-- xaml is moved to separate user control -->
    <local:MyViewModelUserControl />
</DataTemplate>

2.

<DataTemplate DataType="{x:Type local:MyViewModel}">
    <!-- xaml is typed here directly -->
    <Border>
         ...
    </Border>
</DataTemplate>

In 1st case it takes longer to render results than in the 2nd. And this difference is in about 2 times. I posted it as a separate question

Carlyncarlynn answered 27/7, 2016 at 9:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.