uwp should I be using user control inside a data template?
Asked Answered
A

1

5

in my UWP app I was thinking to extract my data template into a seperate user control , i.e: <DataTemplate><local:CustomTemplate/></DataTemplate> and the user control ( customtemplate ) will have that stackpanel or grid which was previously in my DataTemplate directly, along with its bindings, I already know how to achieve this.

My Question is that by extracting out the data template in a user control, would this cause any performance hit? I read somewhere that while doing this each GridViewItem proceeds to execution of InitializeComponent() of the user control is executed and xaml is parsed on UI, which causes performance issues? But if we keep the data Template within same file ( not extracted in a user control ) then no performance issue will occurs. is this true ?

Acentric answered 21/6, 2017 at 13:20 Comment(7)
Why not simply give it a try, and see if it in any way impacts the performance of your application?Hepta
Do you need a code-behind class or a custom view model for the content of the dataTemplate? Otherwise, I see no point in creating the user control.Blowzy
@NahuelIanni I am using ViewModel and binding ItemSource of the grdiview to an ObservableCollection property of the ViewModel. I will be using that same data template on multiple pages that is why I wanted to extract it into a user controlAcentric
@Hepta my pc doesnt have much files to test scenarios with high number of files, bcz when files are low, any performance change will be undetectableAcentric
So you want to deliver the app without testing it with many files? That sounds like a bad idea. If you expect it to work with a large amount of data on the customer's side, you should test that before delivery.Hepta
You can still create a data template shared across views as a resourceBlowzy
@NahuelIanni actually my data template has x:Bind so it needs code behind file as well. how can I share that accross the resources?Acentric
L
7

First, if you purely want to use the same DataTemplate that uses x:Bind across different components, you don't have to wrap all your elements in either a UserControl or Custom Control.

You just need to create a resource dictionary called Templates.xaml that includes all the data templates (with x:Bind!) you want to share, as well as a cs class with the same name like this -

public partial class Templates  
{
    public Templates()
    {
        InitializeComponent();
    }
}

Then in your Templates resource dictionary, add a x:Class attribute to point to the class you just created -

<ResourceDictionary x:Class="xxx.Templates" ..>

Finally you will need to merge this resource dictionary into your App.xaml or a parent resource dictionary -

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Fonts.xaml" />
    <ResourceDictionary Source="Brushes.xaml" />
    <ResourceDictionary Source="Styles.xaml" />
    <local:Templates />
</ResourceDictionary.MergedDictionaries>

Now build and run and it should work. Please refer to Igor's excellent post on this topic that I followed a couple of years ago which has worked for me flawlessly. I was even able to create code-behind stuff in there too.


Now back to your original question, would using a UserControl be bad for performance?

I personally believe the answer is NO in UWP.

Historically in WPF, using a UserControl inside a virtualized items control calls the InitializeComponent() inside the UserControl every time a new data template is created, which leads to performance issues so people tend to use a Custom Control instead.

However, this is no longer the case in UWP, where no matter it's a UserControl, Custom Control or even just a Grid, as long as they have the same exact child elements, they will be loaded the same amount of times. This means that the InitializeComponent inside the UserControl will only be called a small number of times until the virtualized ListView has enough numbers to recycle through the whole list.

But keep in mind that another control wrapper is an additional layer, it will always suck a little bit more memory. So unless you want additional logic on your template such as having dependency properties to show/hide stuff, you don't have to extract its content to put into another UserControl or Custom Control.

I hope my explanation makes sense.

Leclerc answered 21/6, 2017 at 21:58 Comment(7)
Avalue of type Templates could not be added to a dictionary of type IList. This is the error visual studio is giving me. when I try to merge it into App.xaml as you mentionedAcentric
also I want to use 2 things within my data templates. 1. Visual State Manager. 2. Handle Events in code behind ( by accessing the Name properties of the elements. Can I achieve these 2 if I use a data template in resource dictionary? or should I make a user control of data template to achieve these 2 ?Acentric
Try to follow the blog post in details. You must have missed something. Data templates can give you no. 2. If you want adaptive triggers in your VSM, you will have to create a UserControl.Leclerc
also if I make a user control, can I use it to make another user control?Acentric
You mean one UserControl that wraps another? Absolutely.Leclerc
I am able to succesfuly extract data template out in resource dictionary and it works fine, But I can access any Named elements in code behind in Templates.cs class , and also InitializeComponent() . can you please guide me how to do code behind? I want to access elements which are within the data templateAcentric
You need to access them in the Loaded event, like how you normally create a Loaded event handler on a page.Leclerc

© 2022 - 2024 — McMap. All rights reserved.