I have built a UserControl containing a TreeView where each node contains a bunch of controls.
Simplified version of the tree's code:
<UserControl x:Class="MyTestWPF.MyTree"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MyTestWPF"
mc:Ignorable="d"
x:Name="MyTreeUserControl">
<UserControl.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:MyTreeNode}"
ItemsSource="{Binding Nodes}">
<StackPanel Orientation="Horizontal">
<ComboBox>
<ComboBoxItem>Item 1</ComboBoxItem>
<ComboBoxItem>Item 2</ComboBoxItem>
</ComboBox>
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</UserControl.Resources>
<TreeView ItemsSource="{Binding MyTreeProp, ElementName=MyTreeUserControl}" />
</UserControl>
The control's codebehind only has a simple DependencyProperty for the MyTreeProp property created with the propdp snippet.
I then call the control like so:
<local:MyTree MyTreeModel="{Binding Path=MyData}" />
And here's the parent view's DataContext with MyData:
this.DataContext = new {
MyData = new List<MyTreeNode>() {
new MyTreeNode() {
Name = "1",
Nodes = new MyTreeNode[] {
new MyTreeNode() { Name= "2" }
}
}
}
};
The MyTreeNode is simply:
public class MyTreeNode
{
public string Name { get; set; }
public MyTreeNode[] Nodes { get; set; }
}
My question is about passing data into the MyTree control's MyTreeProp.
I initially tried to set the ItemsSource's binding without the ElementName, and setting MyTree's DataContext to this in the constructor, but that threw an exception:
System.Windows.Data Error: 40 : BindingExpression path error:
'MyData' property not found on 'object' ''MyTree' (Name='MyTreeUserControl')'. BindingExpression:Path=MyData;
DataItem='MyTree' (Name='MyTreeUserControl');
target element is 'MyTree' (Name='MyTreeUserControl');
target property is 'MyTreeProp' (type 'List`1')
Why?
- What am I misunderstanding about how the view is attempting to read the
DataContext? - Why does it seem from the error that it is searching for
MyDataon the UserControl? Or am I misreading that? - Is there really no way to pass the value to the UserControl's property, and then use it without the need to reference the
UserControl.Namein each and every element that needs to read it?
--Edit--
Based on the comments, I understand that setting DataContext directly is wrong... but that still leaves the question - what is the correct way to access the UserControl's properties? Does it really require setting a name to the UserControl tag, and then explicitly referencing it by name whenever I need to access the property?