25

I was looking some tutorials on how to create custom controls in WinRT, and I have a question.

Let's say I want to create a simple control that contains some stuff, like a Grid with an image on the left and a couple of TextBlocks on the right.

I mean, something simple like:

<Grid Height="100">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.3*"/>
        <ColumnDefinition Width="0.7*"/>
    </Grid.ColumnDefinitions>
    <Image Source"/Assets/someRandomImage.png"/>
    <StackPanel Grid.Column="1"
                VerticalAlignment="Center">
        <TextBlock Text="Some text"
                   Margin="10,0,10,0"
                   FontSize="24"
                   FontWeight="SemiLight"
                   TextTrimming="CharacterEllipsis"/>
        <TextBlock Text="Some random description..."
                   Margin="10,5,10,0"
                   FontSize="18"
                   FontWeight="Light"
                   Foreground="Gray"
                   TextWrapping="Wrap"
                   TextTrimming="CharacterEllipsis"/>
    </StackPanel>
</Grid>

I would create a UserControl with this content, so I'd be able to see it in the XAML Designer while I'm working on its UI, and I'd add all the Properties and DependencyProperties in the UserControl code behind.

Then I saw that another approach would be to use a Template control, so I'd have to create a class that inherits from the Control class, then use the above XAML code as a template and apply it to the custom control and add all the rest of the logic there.

Of course, I'd also have to add the x:Name property to some those UIElements inside the control to be able to interact with them, but you get the idea.

I was wondering, is it ok to use either one of these two methods, or is better to use one in particular, and why? Also, I like using UserControls since I can see them in the Designer window, and instead I wouldn't be able to do that with a Template, I'd have to run the app and create an instance of the control to see what it actually looks like.

Thanks for your help, I think I'm not the only one with this doubt, so I hope this question will help others as well :D

Sergio

Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
Sergio0694
  • 4,447
  • 3
  • 31
  • 58
  • 1
    Do you add functionality to the UserControl? Or just change how an existing control is displayed? For the latter even a control template would suffice http://www.wpftutorial.net/templates.html – treze Mar 29 '15 at 20:49
  • I add functionality: I usually create some Properties, DependencyProperties for some Bindings and a maybe animations and stuff. As for other features, I usually create a ViewModel for the UserControl and I use that to add methods and internal bindings. – Sergio0694 Mar 29 '15 at 22:12
  • One more note - you can see templated controls in the design view in VS or Blend as long as they don't have any logic that would break the design view. You just have to use an instance of your control in a `UserControl`/`Page` and it should show up. – Filip Skakun Mar 30 '15 at 21:45
  • See also https://stackoverflow.com/questions/47841324/templated-control-vs-custom-control-in-uwp-no-clear-answer-found-online – Filip Skakun Feb 26 '20 at 21:14
  • See also https://stackoverflow.com/questions/1131106/wpf-controltemplate-vs-usercontrol – Filip Skakun Feb 26 '20 at 21:14

2 Answers2

28

TLDR

A custom (templated) control allows an app to use the Template property to replace the control’s internal element tree. If you don’t need/want your control to have that re-templating feature, then use a UserControl as it’s easier.

UserControl

  • A UserControl is a lot easier to create with Visual Studio or Blend giving you a decent design view support.
  • You typically use it to compose a view in your app from multiple controls.'
  • It works best for full screen or full-window views or if you have complex views that you want to break apart in smaller, possibly reusable code chunks.
  • Such view is often backed with a corresponding view model if you choose to adopt the MVVM pattern.

  • One problem with a UserControl is that while you can reuse it in multiple places in your app - it is difficult to make slight adjustments to the way it looks or behave in different places in your app since it doesn't use templates and the UI tree is loaded in the constructor.

  • It is typically only reusable within the scope of the single app.

Custom control

  • A custom control or in some cases templated control is best suited for a small chunk of UI that serves a single purpose - it visualizes a single, specific type of information.
  • A templated control can have its template changed to adjust the visuals for particular use case. It allows you to have a button that looks like a default button in one app, a rounded one in another and one made solely up of images in yet another. It makes it more reusable which makes sense if you make more than one app or want to share your awesome control with the world.
  • A well written custom control is usually reusable in more than one app since it doesn't depend on business logic of particular app.
  • It typically derives from an existing platform control, such as Button, ToggleButton, ContentControl, Slider, TextBox or ListView to add to or override its logic. There are cases though when it makes sense to make one from scratch, subclassing "virtually abstract" Control, ItemsControl, RangeBase, Shape or even FrameworkElement (the last two are not templated).
  • The visual tree of a templated control is loaded when the template is loaded which might occur as late as when the control's visibility is first changed from Collapsed to Visible which allows to defer loading parts of your UI to get performance improvements.
  • Because the control template is only loaded once, these are ideal for use inside any ItemsControl DataTemplate (lists, gridviews, etc). If you were to use a UserControl, your performance could really suffer because the UserControl XAML is parsed over and over again.

Custom panel

A custom panel is yet another type of UI element that allows to customize how it lays out its children.

Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
  • 1
    Your claim that user controls are typically only reusable within the scope of the single app is just not true. I have user controls that are perfectly reusable in all my projects. For the remainder I mostly agree, I would remove that statement. – Philip Stuyck Mar 30 '15 at 07:50
  • Oh, I also have user controls that are reusable in various projects, but typically you strive to make these templated eventually to get these performance improvement and customization support benefits. Note that `Page` is also a `UserControl`, so unless you have apps that share the entire pages - you typically use these per app. If you find you do have a lot of `UserControls` that are shared between apps - consider making them templated and perhaps open source. I've seen someone create an app with a version for each football club in UK - they probably shared all `Pages`, but this is unique... – Filip Skakun Mar 30 '15 at 16:38
  • Thanks for the detailed explanation! I just have another question: if I were to create a custom control, I mean a templated control, would it make any difference if I created a Template in XAML and then applied it to the control, or if I directly built the visual tree at runtime inside my custom control constructor? I find the second option to be easier to use in some situations (where I have just a few UI elements inside my custom control). – Sergio0694 Mar 30 '15 at 20:04
  • I've just noticed this [`GoToElementStateCore()`](https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.frameworkelement.gotoelementstatecore.aspx) method that could do what you are asking, but I still wouldn't recommend that. You should put your template in Themes/Generic.xaml and avoid going against the flow if you want to avoid trouble down the road. – Filip Skakun Mar 30 '15 at 21:08
  • To reiterate a point from Flip's answer, UserControls often combine several controls into a conceptually unified entity, whereas TemplatedControls often extend or modify the behavior of a single existing type of element, like a Button. This can be a helpful distinction to keep in mind when deciding which is appropriate. – Dan Aug 28 '16 at 22:19
  • 1
    I am not sure about the last point "Because the control template is only loaded once..." If the usercontrol is already in a data template, shouldn't it be parsed only once? – Jessica Jun 09 '17 at 14:21
  • I haven't measured it actually, so this could be fake news or outdated recommendations that only made sense for big WPF apps with XBF2. Perhaps nowadays the performance is similar, but historically - each time your `DataTemplate` would create a new instance of a `UserControl`, which in turn would immediately call `InitializeComponent` in the constructor and parse the XAML's XML to create all the elements. A custom/templated control, in turn, wouldn't do much in the constructor. The template would be loaded once when needed and it (its object model?) would be reused by all instances = speed. – Filip Skakun Jun 13 '17 at 05:42
  • 3
    This answer looks interesting. https://stackoverflow.com/a/44686931/1247637 – Jessica Jun 22 '17 at 07:12
  • 2
    It sounds reasonable. UWP is not your grandfather's WPF. You might not need to warm it up much before you start driving! :) Anyways - if you're just componentizing a few parts of your view - you should totally use a `UserControl`. If you're building new interactive behaviors - use a custom control. If you're putting stuff in a list - avoid using either and use as few elements as possible. Then again - these are just general recommendations. You might find that whatever you do - things work fine anyway. You don't have to overoptimize or overthink things until your perf starts sucking. – Filip Skakun Jun 23 '17 at 20:40
  • Yes totally agree. Thanks! – Jessica Jun 23 '17 at 23:28
  • 1
    One important difference is also that a `UserControl` is dervived from `ContentControl` and therefore has a public `Content` property. The users of your control can (accidentally) set this property (e.g. by confusing it with the `DataContext` property) and by that completely erasing the XAML inside your `UserControl`. If your Controls are part of a public API for public reuse I would advice against the use of `UserControl`s – bitbonk May 28 '20 at 10:44
3

Creating a user control is a lot simpler than creating a custom control. For starters a user control has designer support. The disadvantage of a user control is that it is limited in comparison with a custom control.

A user control is excellent if you want to create a control that is a composition of some other controls like in your example but suppose you want to create a special kind of panel, then you really have to create a custom control.

So in summary user control for 'simple' controls user control for complex controls. Any user control can be created by a custom control but not the other way around.

Philip Stuyck
  • 7,344
  • 3
  • 28
  • 39