WPF DataTemplate - x:Key vs DataType="{x:Type XXXX")
Asked Answered
G

1

11

I have a DataTemplate that I want to find using the FrameworkElement.FindResource(). To do that I need to have a key on the data template.

The problem is that x:key and assigning a data type are mutually exclusive. (Reference)

So, once I set the DataType for my template, how do I find the Key value? Is there some formula that converts the DataTemplate into a string for the Key?

(For inquries as to why I need to get the DataTemplate found by Resource see this question.

Gliadin answered 23/12, 2009 at 15:58 Comment(0)
P
20

The x:Key seems to be an object of type System.Windows.DataTemplateKey. So, you can "create" the key for your resource with new DataTemplateKey(typeof(myType)). FindResource will work with this key, since TemplateKey.Equals has been overridden.

Here is a very simple example application:

XAML:

<Window ...>
    <Window.Resources>
        <DataTemplate DataType="{x:Type TextBlock}">
        </DataTemplate>
    </Window.Resources>

    <Button Click="Button_Click">Test</Button>
</Window>

Codebehind:

//using ...

namespace WpfCsApplication1 {
    public partial class Window1 : Window {
        public Window1() {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
            var key = new System.Windows.DataTemplateKey(typeof(TextBlock));
            var r = (DataTemplate)this.FindResource(key);

            MessageBox.Show(r.ToString()); // to show that it worked
        }
    }
}
Pryce answered 23/12, 2009 at 16:22 Comment(5)
This looks great but is a C# solution. Is there any way to do this from XAML directly? For instance I have a DataType template that I'm using everywhere, but I also want to use it as a value in a TemplateSelector as well. Same thing... if I add a key, I lose the data-type matching. If I don't, I'm not sure how to ref it in XAML.Intinction
@MarqueIV: You should be able to reference it in XAML by using {x:Type ...} as the key.Pryce
Tried this... DataTemplate="{StaticResource {x:Type vm:IOPBase}}" but it doesn't work. Crashes. (FYI, I know the type is correct as the template has 'DataType="{x:Type vm:IOPBase}"' which works fine.) Thoughts?Intinction
@MarqueIV: Good question, I thought it would work. Could you create a new question and post a minimal working example?Pryce
I had a feeling it wouldn't work, because even by your own example, the type isn't the key... a DataTemplateKey initialized with the data type is. Yeah... I'll add a new one...Intinction

© 2022 - 2024 — McMap. All rights reserved.