问题描述
我正在尝试在特定类型的TreeViewItem
上设置“展开时扩展”功能,如下所示:
<UserControl x:Class="ImprovedDirectory.Views.DirectoryView"
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:ImprovedDirectory.Views"
xmlns:vms="clr-namespace:ImprovedDirectory.viewmodels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<DataTemplate x:Key="CollapsedItem" DataType="{x:Type vms:DirectoryItemviewmodel}">
<TextBlock
Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"
Margin="5"/>
</DataTemplate>
<DataTemplate x:Key="ExpandedItem" DataType="{x:Type vms:DirectoryItemviewmodel}">
<StackPanel DataContext="{Binding}">
<TextBlock
Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"
Margin="5"
Grid.Row="0"/>
<TextBlock
Text="{Binding Number,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"
Margin="2.5"
Grid.Row="1"/>
<TextBlock
Text="{Binding Email,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"
Margin="2.5"
Grid.Row="2"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<TreeView x:Name="DirectoryTreeView" ItemsSource="{Binding Groups}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vms:DirectoryGroupviewmodel}" ItemsSource="{Binding Items,UpdateSourceTrigger=PropertyChanged}">
<TextBlock
Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"
Margin="5"/>
</HierarchicalDataTemplate>
<Style targettype="{x:Type TreeViewItem}">
<Style.Setters>
<Setter Property="ItemTemplate" Value="{StaticResource CollapsedItem}"/>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ItemTemplate" Value="{StaticResource ExpandedItem}"/>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.Resources>
</TreeView>
上面的输出如下,我不知道为什么:
我知道绑定确实很简单,我很想念它们。但是,我目前还不确定,我已经分别测试了DataTemplate
中的每个UserControl.Resources
元素,并且它们均按预期工作。
我也遇到了一个问题,那就是Style
会覆盖小组的格式以及项目的格式,所以我想第二个问题是如何定义具体的{{1 }}成为项目而非所有对象的主要输出。
任何帮助将不胜感激。
解决方法
您看到的输出来自以下事实:您以DataTemplate
样式将ItemTemplate
设置为TreeViewItem
,但没有层次结构的表示,例如ItemsSource
的儿童。
如果将模板更改为HierarchicalDataTemplate
中的TreeView
,则会得到层次结构,但我认为这样做的行为与预期的不同。展开一个项目并随后选择一个或另一个项目时,您会看到所有子级的模板都在变化并且选择被破坏了。
代替交换数据模板,您可以通过将两个模板组合为一个模板并对触发器中的IsSelected
属性做出反应,以更简单的方式获得所需的结果,从而更改隐藏的控件的可见性未选中。
<TreeView x:Name="DirectoryTreeView"
ItemsSource="{Binding Groups}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type vms:DirectoryGroupViewModel}"
ItemsSource="{Binding Items}">
<StackPanel>
<TextBlock Text="{Binding Name}"
VerticalAlignment="Center"
Margin="5"/>
<TextBlock x:Name="NumberTextBlock"
Text="{Binding Number}"
VerticalAlignment="Center"
Margin="2.5"
Visibility="Collapsed"/>
<TextBlock x:Name="EmailTextBlock"
Text="{Binding Email}"
VerticalAlignment="Center"
Margin="2.5"
Visibility="Collapsed"/>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},Path=IsSelected}" Value="True">
<Setter TargetName="NumberTextBlock" Property="Visibility" Value="Visible"/>
<Setter TargetName="EmailTextBlock" Property="Visibility" Value="Visible"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
除了触发器之外,您还可以使用BooleanToVisibilityConverter
直接绑定Visibility
。
<TreeView x:Name="DirectoryTreeView"
ItemsSource="{Binding Groups}">
<TreeView.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</TreeView.Resources>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type vms:DirectoryGroupViewModel}"
ItemsSource="{Binding Items}">
<StackPanel>
<TextBlock Text="{Binding Name}"
VerticalAlignment="Center"
Margin="5"/>
<TextBlock Text="{Binding Number}"
VerticalAlignment="Center"
Margin="2.5"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},Path=IsSelected,Converter={StaticResource BooleanToVisibilityConverter}}"/>
<TextBlock Text="{Binding Email}"
VerticalAlignment="Center"
Margin="2.5"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},Converter={StaticResource BooleanToVisibilityConverter}}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>