Create a Master/Details View based on TreeView Control in Silverlight
I have a TreeNode class with following properties
public string Name { get; set; }
public string Description { get; set; }
public bool AllowMultiples { get; set; }
private ObservableCollection<TreeNode> _childNodes = new ObservableCollection<TreeNode>();
In my UI I want to display tree in left panel and selected items details in right side.
My XAML looks like following:
<UserControl.Resources>
<win:HierarchicalDataTemplate x:Key="ChildTemplate" ItemsSource="{Binding ChildNodes}">
<TextBlock FontStyle="Italic" Text="{Binding Path=Name}" />
</win:HierarchicalDataTemplate>
<win:HierarchicalDataTemplate x:Key="NameTemplate"
ItemsSource="{Binding Path=ChildNodes}"
ItemTemplate="{StaticResource ChildTemplate}">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
</win:HierarchicalDataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Document Hierarchy" Margin="0,0,43,0" FontSize="13" />
<toolkit:TreeViewDragDropTarget Grid.Row="1" Grid.Column="0" BorderThickness="-1">
<controls:TreeView BorderThickness="0" ItemTemplate="{StaticResource ChildTemplate}" x:Name="treeView" ItemsSource="{Binding}">
</controls:TreeView>
</toolkit:TreeViewDragDropTarget>
<TextBlock Text="Properties" FontSize="11" Grid.Column="1" Grid.Row="0" />
<Grid Grid.Row="1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" ></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock x:Name="AlloMultPropLabel" Text="Allow Multiple" Grid.Column="0" Grid.Row="0"></TextBlock>
<RadioButton x:Name="AllowMulti" GroupName="GrpAllowMulti" Content="True" Grid.Column="1" Grid.Row="0"/>
<RadioButton x:Name="AllowMulti2" GroupName="GrpAllowMulti" Content="False" Grid.Column="2" Grid.Row="0" IsChecked="True" />
<TextBlock x:Name="DescPropLabel" Text="Description" HorizontalAlignment="Left" Width="74" Grid.Row="2" ></TextBlock>
<TextBox x:Name="DescProp" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2" Text="{Binding Description}" /> 开发者_运维百科
</Grid>
Using http://www.silverlight.net/learn/quickstarts/bindingtocontrols/ as my reference I have set the LayoutRoot.DataContext to CollectionViewSource as below:
public ObservableCollection<TreeNode> itemsSource = new ObservableCollection<TreeNode>()
{
new TreeNode("Root", "ths is test"),
new TreeNode("Secondary","Second node"),
};
public MainPage()
{
InitializeComponent();
//treeView.DataContext = itemsSource;
LayoutRoot.DataContext = new CollectionViewSource { Source = itemsSource };
}
When I run this project I notice that the description is always set to first items description. It is not getting changed based on selection.
Any pointers to get this right?
You have bound the TextBox to "{Binding Description}". It will using the same DataContext that the TreeView starts with hence it shows the description of the top item.
In order to for the textbox to follow the selected item in the tree its data context needs to be bound to the SelectedItem
of the Treeview. I'd be inclined to placing the "Detail" display in its own Grid and manage its layout in there, this would be a good place to update the DataContext
:-
<Grid DataContext="{Binding SelectedItem, ElementName=treeView}">
<Grid.ColumnDefinitions>
<Grid.ColumnDefinition Width="Auto" />
<Grid.ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<Grid.RowDefinition Height="Auto" />
<Grid.RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="Name" Grid.Row="0" Grid.Column="0" />
<TextBox Text="{Binding Name}" Grid.Row="0" Grid.Column="1"/>
<TextBlock Text="Description" Grid.Row="1" Grid.Column="0" />
<TextBox Text="{Binding Description}" Grid.Row="1" Grid.Column="1"/>
</Grid>
Note the binding on the Grid DataContext it uses the treeView as the source object and binds to the SelectedItem
.
精彩评论