I have two classes, which reference the third:
class Data1
{
public Named Xxx { get; set; }
public SomeClass1 Foo { get; set; }
...
}
class Data2
{
public Named Yyy { get; set; }
public SomeClass2 Bar { get; set; }
...
}
class Named
{
public string Name { get; set; }
...
}
Now, I would like to display both Data1 & Data2:
<TreeView DataContext={Binding Path=Data1}>
<TreeView.Items>
<TreeViewItem>
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<ContentControl xml:space="preserve">Name: </ContentControl>
<ContentControl Content="{Binding Path=Xxx.Name}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem><!-- somehow display Foo --></TreeViewItem>
<!-- More TreeViewItems, specific to Data1 -->
</TreeView.Items>
</TreeView>
<TreeView DataContext={Binding Path=Data2}>
<TreeView.Items>
<TreeViewItem>
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<ContentControl xml:space="preserve">Name: </ContentControl>
<ContentControl Content="{Binding Path=Yyy.Name}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem><!-- somehow display Bar --></TreeViewItem>
<!-- More TreeViewItems, specific to Data2 -->
</TreeView.Items>
</TreeView>
So, markup is different, except for TreeViewItem that displays Named class. I would like to reuse markup for this TreeViewItem. It is too simple to make UserControl of it, but it is still a little more complicated than shown in example. So, I would really like to do something like this:
<ResourceDictionary>
<TreeViewItem x:Key="Named">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<ContentControl xml:space="preserve">Name: </ContentControl>
<ContentControl Content="{Binding Path=Name}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
</ResourceDictionary>
And then just use it like this:
<TreeView DataContext={Binding Path=Data1}>
<TreeView.Items>
<StaticResource ResourceKey="Named" />
</TreeView.Items>
</TreeView>
As you can see, Data1‘s property name for Named is Xxx, while Data2‘s property name for Named is Yyy. So, I have to pass that somehow to my resource. But how?
E.g. how do I set the DataContext of this StaticResource subtree to Xxx for Data1?
Something like this doesn’t work:
<StaticResource ResourceKey="Named" DataContext={Binding Path=Xxx} />
Sorry for the long question.
Edit:
All I want is a piece of XAML, capable of displaying a Named instance. So, I want to be able to specify where to get the instance (from Xxx or Yyy) outside of this piece, so I can reuse it.
Edit2: here is the solution with ControlTemplate, however it doesn’t work well: the TreeViewItem becomes unselectable. What’s wrong?
<ControlTemplate x:Key="Named" TargetType="TreeViewItem">
<TreeViewItem>
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Name: " />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
</ControlTemplate>
<!-- now use the template: -->
<TreeView>
<TreeView.Items>
<TreeViewItem Template="{StaticResource Named}"
DataContext="{Binding Path=Xxx}" />
...
OK, I took a nap today and when I woke up, I suddenly realized what the answer is! Here it is: