Keith Stein Keith Stein - 3 months ago 27 Question

Creating a WPF control that uses datatemplates

I'm trying to build a control that will display items in a sort of scheduling grid, so that they are placed horizontally depending on what category their in, and vertically depending on what time they are scheduled and how much time the item will take to complete. I am currently inheriting from System.Windows.Controls.Control and the default style and template is shown below:

<Style TargetType="KHS:TimeGrid">
<Setter Property="Template">
<ControlTemplate TargetType="KHS:TimeGrid">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<Grid Name="PART_HeaderGrid" DockPanel.Dock="Top">
<ColumnDefinition Width="{Binding ActualWidth, ElementName=TimeColumn}"/>

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<Grid Name="PART_BodyGrid">
<ColumnDefinition Name="TimeColumn" Width="Auto"/>

For my items, I simply use this interface:

Public Interface ITimeGridItem
Property StartTime As Date
Property Duration As TimeSpan
End Interface

Rows are added to the "BodyGrid" for each increment of time (representing 15 minutes by default) and items are given Grid.Row and Grid.RowSpan values based on their start times and durations.

My problem comes in when I try to implement DataTemplates for items. I'm currently trying to use ContentPresenters to display the items. It would be easy to create an ItemTemplate property for the TimeGrid and just use it for all items, but what if I need to template items of different types with unique templates?

That got me thinking how other controls can have DataTemplates added to their Resources collection with different DataTypes, and the control knows to search the resources and pick the right template. Unfortunately I haven't been able to figure out how to implement that. Anyone know how I can accomplish this? It must be possible since Microsoft does it in their controls.


Oh my god I can't believe it was so simple. I actually have to give some credit to @ed-plunkett for his all-to-obvious comment. I looked a bit harder and by accident discovered that if I changed this:

<DataTemplate DataType="local:TestItem">

to this:

<DataTemplate DataType="{x:Type local:TestItem}">

it works!

A few minutes later, I found this article:

*sigh* I wish I had found that earlier.

So as long as I use the {x:Type} syntax I can put the DataTemplate anywhere in the scope and it will be applied.