Selecting DataTemplate by DataType

Mar 2, 2010 at 6:13 PM

Michael,

I had to resort to TemplateSelectors (which is an anti-pattern ), after numerous attempts to avoid it. I can see 2-3 years down the road how messy such code will look.

I tried:

- Markup extensions, but it looks that with DataTemplate WPF doesn't accept inherited classes niether from TypeExtension nor from MarkupExtension.

- Generic syntax in XAML, which by the works, but only for built-in classes (which is strange). So this actually can be placed in XAML and it works:

<DataTemplate DataType="{x:Type TypeName=System:Nullable`1[[System.Int32]]}">
</DataTempalte>

- Tried unwrapping ObjectInstance<T> with data templates, it works, but UpdateControls doesn't update UI when commands are invoked.

Could you please give some/any guidance of what would be the best way to solve this?
I am trying to just place all possible views for different ViewModels in dataTemplates. When ViewModel shows up somewhere in the course of using the app the correct DataTemplate with appropriate View for that view model is applied.

Thank you,

Ivan

 

Coordinator
Mar 4, 2010 at 2:42 PM
Edited Mar 4, 2010 at 2:43 PM

I found that you could define the type as a static resource using a markup extension, then reference that type in your data template. I added a markup extension to the UpdateControls code base specifically for this purpose. Here's how I'm using it in my current project:

 

<Window x:Class="Absg.IonOnline.ContractDesigner.Client.MainWindow"
xmlns:homePane="clr-namespace:Absg.IonOnline.ContractDesigner.Client.Panes.HomePane"
xmlns:contractHeaderListPane="clr-namespace:Absg.IonOnline.ContractDesigner.Client.Panes.ContractHeaderListPane"
xmlns:u="clr-namespace:UpdateControls.XAML;assembly=UpdateControls.XAML" >
<Window.Resources>
<u:WrappedType x:Key="HomeVM" Type="homePane:HomeViewModel"/>
<DataTemplate DataType="{StaticResource HomeVM}">
<StackPanel>
<homePane:HomeUserControl/>
</StackPanel>
</DataTemplate>
<u:WrappedType x:Key="ContractListVM" Type="contractHeaderListPane:ContractHeaderListViewModel"/>
<DataTemplate DataType="{StaticResource ContractListVM}">
<StackPanel>
<contractHeaderListPane:ContractHeaderListUserControl/>
</StackPanel>
</DataTemplate>
</Window.Resources>
</Window>

 

Mar 4, 2010 at 6:12 PM

Wow, this is great!

Because I really don't like if..then..if..then.. type of code in template selectors. Which is what Microsoft guys recommended in here:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a3d5e6a4-2af1-4b8c-8d33-6a2ab72dbdf6

Thanks! I will try right now.

Mar 4, 2010 at 10:28 PM

This solution works, but I have couple of minor issues with it.

- In VS XAML editor complains "Error 170 Property 'Resources' does not support values of type 'RuntimeType'. " and doesn't render UI, while everything gets compiled and works fine.

- Is there a way to move dataTemplates to a different file? It keeps telling me that I must include x:Key for dataTemplates, but when I do so they don't get applied by DataType any more, only by x:Key.

Thank you!