WPF: Find Resources from UserControl within DataTemplateSelector class

Elisabeth picture Elisabeth · Dec 14, 2010 · Viewed 9.4k times · Source

I know there is this thread: How to find a resource in a UserControl from a DataTemplateSelector class in WPF?

asking the same.

BUT... I am not satisfied with the answer! THERE MUST be a way to grab the Resources of the

UserControl containing the ContentControl/Presenter declaring this:

ContentTemplateSelector="{StaticResource MySelector}" 

Each derived DataTemplateSelector class a parameter in its SelectedTemplate Method =>

container which is typeof DependencyObject.

Well container is in my case the contentcontrol.

Would it not be possible to climb up the visual tree starting at "contentcontrol" and try to get the UserControl via FindAncestor ?

Answer

Quartermeister picture Quartermeister · Dec 15, 2010

Yes, you can cast the container parameter to FrameworkElement and call FindResource to do a resource lookup starting at the ContentPresenter. For example:

Code:

public class MySelector
    : DataTemplateSelector
{
    public override DataTemplate SelectTemplate
        (object item, DependencyObject container)
    {
        // Determine the resource key to use
        var key = item.ToString() == "a" ? "one" : "two";
        // Find the resource starting from the container
        return ((FrameworkElement)container).FindResource(key) as DataTemplate;
    }
}

XAML:

<UserControl
    x:Class="WpfApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    >
    <UserControl.Resources>
        <DataTemplate x:Key="one">
            <TextBlock>Template One</TextBlock>
        </DataTemplate>
        <DataTemplate x:Key="two">
            <TextBlock>Template Two</TextBlock>
        </DataTemplate>
        <local:MySelector x:Key="MySelector"/>
    </UserControl.Resources>
    <StackPanel>
        <ContentPresenter
            ContentTemplateSelector="{StaticResource MySelector}"
            Content="a"/>
        <ContentPresenter
            ContentTemplateSelector="{StaticResource MySelector}"
            Content="b"/>
    </StackPanel>
</UserControl>