Long Story Short (TL;DR)
When trying to come up with a graphical representation for some custom data structure, how am I supposed to know which template to use?
You would create data templates for your data types. The key differences are:
Short Story Long
Misconception
I don't get templates. I don't understand what "level" to instantiate a template, and how to even know what templates are available.
I think your mental picture of templates misleads you. There are different types of templates that serve different purposes, not levels. These template types are neither part of a hierarchy, where one supersedes another, nor are they interchangable.
Control Template
Purpose
In the following, by control we mean the base type Control
or a type that is directly or indirectly derived from it, like Button
, ComboBox
or TextBlock
. Let us pick Button
as an example to see how controls are designed. A button has different states like Mouse Over or Pressed and can be clicked to execute an action. These states are implemented as properties IsMouseOver
and IsPressed
and the signal that it is clicked is exposed as Click
event and so on. Now you have a fully functional button, but no graphical interface to interact with.
This is where control templates come into play. They define the visual representation and behavior of a control. Please note the word visual, because that is the key point of templates, to decouple the logic or core of any control from the way it is displayed. What we mean by visual behavior is what a user experiences when interacting with the control. You could decide that a button changes color when hovering over it with the mouse or you could flicker it. This is also part of a control template specified in various ways, including animations, triggers or visual states.
But why? In the past UI frameworks were often written completely in code, e.g. C++, not using markup languages like XAML. Controls were drawn in code using drawing primitives or pixel by pixel. Visuals, behavior and logic were baked into a type. In order to adapt visuals or interaction, you would have to derive a custom control and draw it yourself or you wrote controls from scratch. This is cumbersome and harms maintainablity, as well as flexibility.
Looks are Subjective
There are many reasons why you would change the visual representation or behavior of controls:
- Operating System: Each OS may have a distinct theme. If your application should convey this native look and feel, you have to provide a suitable theme. By the way, this is exactly what WPF already does out-of-the-box: It has built-in themes (styles and control templates) for each supported Windows OS version.
- Interaction: A desktop device is very different from a touch enabled device, because the input methods are different, like keyboard, mouse, fingers or stylus.
- Accessibility: E.g. Think of color deficiencies (red, green, ...), where certain color schemes need to be available and interchangable.
Instead of deriving a new button for each case, you can now simply define a control template for each in XAML. You would still have a single button type, since its implementation never changed.
Definition and Usage
A ControlTemplate
is usually defined in XAML within a Style
, directly assinged to the Template
property of a control or put into a resource dictionary and referenced where needed, but it can also be built in code.
Summary
A control template helps to separate the logic or core of a control from its visual representation and behavior. WPF provides styles and control templates for built-in types. If you want to change the visual apprearance or behavior of any control, write a custom control template for it.
Guidance for You
Create a control template for a control if you author custom controls or themes or if you want to customize the visual tree of a control in general, including changing is visual apprearance or behavior. Each built-in WPF control has a default style and control template described here.
Resources
Data Templates
Purpose
As its name suggests, a DataTemplate is a template for data. Data is any structure you define that carries information, e.g. a Person
class with name and date of birth, maybe even an image. Now we face the same issue as for controls: How to visually represent these data? Do we want to bake UI controls into our data models? No, we want to decouple our data from the way it is displayed, since those are completely separate concerns.
Looks are Subjective Again
- Operating System: If we display an image of a person, we want its design to match the operating system theme, like frame colors or corner rounding.
- Screen space: Devices differ in size, on one we might display the image of our person right away in full size, on others we might scale or hide it completely.
- Information need: If we have a hierarchical, vertical list of employees to select, we do not want an image there, but we want to see it in the details view of the selected person.
Again, instead of copying, deriving and coupling your data to views, you have a single data type and multiple data templates, each tailored to a specific information need and scenario.
Definition and Usage
A DataTemplate
is usually defined in XAML and assinged to the ContentTemplate
property of a ContentControl
(single item) or the ItemTemplate
property of an ItemsControl
(multiple items) or put in a resource dictionary and referenced where needed. You can define it in code, too.
Within a data template, you use bindings to reference data. Please be aware, that your data type needs to implement the INotifyPropertyChanged
interface, otherwise bindings will not be notified when a property changes. For collection properties, use OberservableCollection<T>
, otherwise changing the collection by e.g. adding or removing items will not be notified to bindings either.
Special Case for Hierarchies
Data can be hierarchical, like employees as part of a department and departments as part of a company. For this case there is a special type HierarchicalDataTemplate
. It is used in the TreeView
control. It is just the same as a regular data template with the exception that it allows you to specify a child items source via its ItemsSource
property and also a child data template via its ItemTemplate
property. Think of it as if you would nest multiple items controls, but through a template instead. This allows homogenous as well as heterogenous data hierarchies to be displayed individually.
Practices to Avoid
Data templates are for data and control templates for controls. Technically you can write a control template instead of a data template and nothing can stop you from doing it, not even the desperate screams of WPF developers bleeding from their eyes. Never do that. Say it.
Summary
Data templates separate your data from their visual representation.
Guidance for You
When trying to come up with a graphical representation for some custom data structure, how am I supposed to know which template to use?
This is exactly your case. Whenever you use or create a data type that needs a custom appearance or behavior in the user interface, create a data template. If you want to reuse it in multiple places, put it in a resource dictionary and include it in the application resources or locally where needed. If no data template is defined, WPF will display the result of the ToString
method by default.
More Complex Scenarios
If you ever run into a case, where you want to create a complex control for your data, e.g. an input mask for a Person
requiring custom logic that cannot be expressed by a template only, consider creating a UserControl
or a custom control from scratch instead.
Resources
Items Panel Template
Purpose
An ItemsPanelTemplate
is a very specific type of template only applicable to ItemsControl
s. It is used to change its Panel
. A panel controls how the items within the items control are arranged, sized and ultimately rendered.
WPF provides multiple panels for hosting items, e.g.:
Canvas
DockPanel
Grid
StackPanel
WrapPanel
- ...
Each of these panels displays items in a distinct way. A StackPanel
places one item after another, either vertically or horizontally. A WrapPanel
places them in a line and overflows to the next line, if there is not enough horizontal space available. A Grid
lets you define a tabular layout.
Please be aware that some controls use a virtualizing panel by default in order to improve performance. Most panel in WPF are not virtualizing and could cause issues in these cases.
Even Layouts are Subjective
By default an standard ListBox
would stack items vertically. This is not desireable in all situations. Maybe you want to display them in line with overflow, like a WrapPanel
does. In order to change that, your would have to derive the ListBox
and override methods to create your own, custom one, although nothing really changes, except for the layout. This would be bad in multiple regards and is the reason why all ItemControl
s provide a way to exchange the items panel without altering the control itself.
Definition and Usage
An ItemsPanelTemplate
is usually defined in XAML within a Style, directly assinged to the ItemsPanel
property of an ItemsControl
or put into a resource dictionary and referenced where needed. It can also be defined in code.
Summary
Items panel templates are used to change the Panel
of an ItemsControl
.
Guidance for You
Create a custom ItemsPanelTemplate
, if you want to change arrangement of items displayed within an ItemsControl
by using a suitable Panel
, e.g. one of the built-in panels.
Resources