Why using UserControl inside DataTemplate is slower than direct xaml?
Asked Answered
A

3

3

I have code as this one:

<ListBox ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type local:MyViewModel}">

           <!-- xaml is typed here directly -->
           <Border>
               ...
           </Border>

        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

And xaml inside the DataTemplate is big (more than 200 lines).

I want to move xaml which is inside the DataTemplate into a separate UserControl to make it easier to edit and maintain. I do next:

<ListBox ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type local:MyViewModel}">

            <!-- xaml is moved to separate UserControl -->
            <local:MyViewModelUserControl />

        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

The issue I run into is that rendering/processing the second code (with UserControl) takes about 2 times longer than the 1st code. Any ideas how to deal with it?

NOTE: I'm moving not the ListBox, but the xaml which is inside the DataTemplate. The reason is not to reuse this code, but to minimize the main file where the ListBox is placed. Other thing is that I have several DataTemplates inside the ListBox (for several ViewModels) and the xaml is really huge. That's why I want to move this xaml (which is inside the DataTemplate) to a separate control.

Afghan answered 27/7, 2016 at 10:27 Comment(0)
T
4

I know this is an old question, but I ran into this issue recently as well. There is significant overhead in creating user controls in WPF which seems to come from connecting a code-behind class file to the XAML. If all you are trying to do is move XAML to another location, simply define your DataTemplate in a ResourceDictionary in another file, and load it as a StaticResource. This will provide a few advantages:

(1) Ability to use x:Name for elements, which is not allowed in an inline DataTemplate.

(2) Performance. A DataTemplate with direct XAML is orders of magnitude faster than a UserControl in a DataTemplate.

(3) Cleanliness. You can define the DataTemplate wherever you like (a resource dictionary in the same file, near where you're using it, a different file, etc.) and refer to it as a StaticResource.

Takeoff answered 27/4, 2018 at 14:23 Comment(0)
C
1

In my opinion, there is no need to separate the Listbox into a separate UserControl as of now, if you’re using this ListBox only at one place. Anyways if you’re so much concerned about optimizing you code and creating reusable controls, then you can create a separate UserControl. But you cannot have a viewmodel for a reusable usercontrol, since it’s a view based thing.

You have to bind the required properties of the listbox to Dependency Properties and then create the UserControl. By doing so, you’re not violating the MVVM pattern as well as you’re making the control available for others to reuse.

The delay caused is not due to what you did. It’s probably due to data fetching time or some other process causing the application to lag.

Communitarian answered 27/7, 2016 at 10:52 Comment(4)
I'm moving not the ListBox, but the xaml which is inside the DataTemplate. The reason is not to reuse this code, but to minimize it in main file where the ListBox is placed. Other thing is that I have several DataTemplates inside the ListBox (for several ViewModels) and the xaml is really huge. That's why I want to move this xaml (which inside the DataTemplate) to a separate control. I've added this info to the answer as well. Sorry, if I described the case not clearly.Afghan
But defining data templates in a separate file is not so good for better maintainability and readability. A list will have its own datatemplate or datatemplates. It's not an issue. If creating a reusable list control, it is fine. But moving your datatemplate into a separate file doesn't sound that good.Communitarian
I have a UserControl which displays an item (of some ViewModel) and contains behaviour of this item. I put this control inside the ListBox.ItemTemplate. That's what you can see in the second code in the question. And it appeared that using UserControl inside ItemTemplate of the ListBox is slower that to write the same xaml directly inside ListBox.ItemTemplate (you can see it in the 1st code above). That's the issue.Afghan
Please post the code of MyViewModelUserControl. I don't think the issue is caused since you moved the code to another xaml. Maybe the data fetching or data has become larger, which is causing the issue.Communitarian
B
0

You can simplify your "MyViewModelUserControl" - instead of inheriting from UserControl you can inherit directly from Border and do so in its XAML as well (Border instead of UserControl as a root element). That will give you the same performance as you had before, but you can keep it in a separate Control.

Bowlder answered 18/10, 2018 at 20:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.