HierarchicalDataTemplate treeViewitems 不可点击
HierarchicalDataTemplate treeViewitems are not clickable
我有下面的 XAML 片段,它创建了一个树视图并用 TreeViewItems 填充它。
Converter 简单地获取名称并返回一个带有 2 个不同颜色字符串的 StackPanel。
我发现我实际上可以在视觉上使用该堆栈面板的唯一方法是将它设置在 TreeViewItem 的 header 中,但是这不能以最佳方式工作,因为 TreeViewItem 已经以编程方式创建。
结果是无法点击label(header)但是看起来很花哨,但是我发现label前面有个大大的space可以点击,它必须来自生成的 TreeViewItem。
我真的需要标签包含 2 个文本块的堆栈面板,有解决方案吗?
<UserControl.Resources>
<XmlDataProvider x:Key="MyXmlProvider" Source="LogansTest.xml" XPath="/Items"/>
<customScripts:NameGeneration x:Key="NameGeneration"/>
<HierarchicalDataTemplate x:Key="NodeTemplate" ItemsSource="{Binding XPath=./*}">
<TreeViewItem x:Name="nodetext"/>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter TargetName="nodetext" Property="Header" Value="{Binding Converter={StaticResource NameGeneration}}"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</UserControl.Resources>
编辑
根据 mm8 的建议,我编辑了我的代码,我完整地上传了我的 XAML,它不再生成树,我对 XAML 很陌生,所以我看不出我做错了什么,呵呵。
运行 一些测试,转换器没有被调用,树视图在它拥有 XML 文件的所有节点之前只是空的
<UserControl x:Class="XmlOutline.OutlineWindowControl"
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:vsshell="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
xmlns:customScripts="clr-namespace:XmlOutline.CustomScripts"
Background="{DynamicResource {x:Static vsshell:VsBrushes.WindowKey}}"
Foreground="{DynamicResource {x:Static vsshell:VsBrushes.WindowTextKey}}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Name="MyToolWindow">
<UserControl.Resources>
<XmlDataProvider x:Key="MyXmlProvider" Source="LogansTest.xml" XPath="/Items"/>
<customScripts:NameGeneration x:Key="NameGeneration"/>
</UserControl.Resources>
<Grid x:Name="TreeGrid" DataContext="MyXmlProvider">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TreeView Name="TreeItems" Visibility="Hidden"
ItemsSource="{Binding Source={StaticResource MyXmlProvider}}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VirtualizingStackPanel.IsVirtualizing="False"
VirtualizingStackPanel.VirtualizationMode="Standard"
Background="#252525"
SelectedItemChanged="TreeView_OnSelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding XPath=./*}"/>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter Property="Header" Value="{Binding Converter={StaticResource NameGeneration}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</Grid>
</UserControl>
编辑
这是每当打开新 XML 文档时设置新数据源的代码。
var provider = new XmlDataProvider()
{
Source = new Uri(gotFocus.Document.Path + gotFocus.Document.Name),
XPath = "./*"
};
OutlineWindowInstance.TreeItems.DataContext = provider;
顺便说一下,整个 GIT 存储库可以在这里找到:
https://github.com/LoganLabster/VsXmlOutline
您不应该在 HierarchicalDataTemplate
中创建另一个 TreeViewItem
容器。尝试定义一个 ItemContainerStyle
来设置 Header
属性:
<TreeView ItemsSource="{Binding Source={StaticResource MyXmlProvider}}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding XPath=./*}" />
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter Property="Header" Value="{Binding Converter={StaticResource NameGeneration}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
感谢@mm8,我找到了答案,一旦我弄明白了,它真的很简单(花了太长时间,doh)。
我没有将 StackPanel 设置为 treeviewitem header,而是在 XAML 中构建了 StackPanel 并一次设置一个值,瞧,它起作用了。
<UserControl x:Class="XmlOutline.OutlineWindowControl"
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:vsshell="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
xmlns:customScripts="clr-namespace:XmlOutline.CustomScripts"
Background="{DynamicResource {x:Static vsshell:VsBrushes.WindowKey}}"
Foreground="{DynamicResource {x:Static vsshell:VsBrushes.WindowTextKey}}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Name="MyToolWindow">
<UserControl.Resources>
<XmlDataProvider x:Key="MyXmlProvider" Source="LogansTest.xml" XPath="/Items"/>
<customScripts:NameGeneration x:Key="NameGeneration"/>
</UserControl.Resources>
<Grid x:Name="TreeGrid" DataContext="MyXmlProvider">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TreeView Name="TreeItems" Visibility="Hidden"
ItemsSource="{Binding}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VirtualizingStackPanel.IsVirtualizing="False"
VirtualizingStackPanel.VirtualizationMode="Standard"
Background="#252525"
SelectedItemChanged="TreeView_OnSelectedItemChanged"
TreeViewItem.Expanded="TreeViewItem_Expanded"
TreeViewItem.Collapsed="TreeViewItem_Collapsed">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate x:Name="myTest" ItemsSource="{Binding XPath=./*}">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="Title" Foreground="LightSkyBlue" FontSize="14"/>
<TextBlock x:Name="SubTitle" Foreground="YellowGreen" FontSize="13"/>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter TargetName="Title" Property="Text" Value="{Binding Path=Name}"/>
<Setter TargetName="SubTitle" Property="Text" Value="{Binding Converter={StaticResource NameGeneration}}" />
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</UserControl>
我有下面的 XAML 片段,它创建了一个树视图并用 TreeViewItems 填充它。 Converter 简单地获取名称并返回一个带有 2 个不同颜色字符串的 StackPanel。 我发现我实际上可以在视觉上使用该堆栈面板的唯一方法是将它设置在 TreeViewItem 的 header 中,但是这不能以最佳方式工作,因为 TreeViewItem 已经以编程方式创建。
结果是无法点击label(header)但是看起来很花哨,但是我发现label前面有个大大的space可以点击,它必须来自生成的 TreeViewItem。 我真的需要标签包含 2 个文本块的堆栈面板,有解决方案吗?
<UserControl.Resources>
<XmlDataProvider x:Key="MyXmlProvider" Source="LogansTest.xml" XPath="/Items"/>
<customScripts:NameGeneration x:Key="NameGeneration"/>
<HierarchicalDataTemplate x:Key="NodeTemplate" ItemsSource="{Binding XPath=./*}">
<TreeViewItem x:Name="nodetext"/>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter TargetName="nodetext" Property="Header" Value="{Binding Converter={StaticResource NameGeneration}}"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</UserControl.Resources>
编辑
根据 mm8 的建议,我编辑了我的代码,我完整地上传了我的 XAML,它不再生成树,我对 XAML 很陌生,所以我看不出我做错了什么,呵呵。 运行 一些测试,转换器没有被调用,树视图在它拥有 XML 文件的所有节点之前只是空的
<UserControl x:Class="XmlOutline.OutlineWindowControl"
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:vsshell="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
xmlns:customScripts="clr-namespace:XmlOutline.CustomScripts"
Background="{DynamicResource {x:Static vsshell:VsBrushes.WindowKey}}"
Foreground="{DynamicResource {x:Static vsshell:VsBrushes.WindowTextKey}}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Name="MyToolWindow">
<UserControl.Resources>
<XmlDataProvider x:Key="MyXmlProvider" Source="LogansTest.xml" XPath="/Items"/>
<customScripts:NameGeneration x:Key="NameGeneration"/>
</UserControl.Resources>
<Grid x:Name="TreeGrid" DataContext="MyXmlProvider">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TreeView Name="TreeItems" Visibility="Hidden"
ItemsSource="{Binding Source={StaticResource MyXmlProvider}}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VirtualizingStackPanel.IsVirtualizing="False"
VirtualizingStackPanel.VirtualizationMode="Standard"
Background="#252525"
SelectedItemChanged="TreeView_OnSelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding XPath=./*}"/>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter Property="Header" Value="{Binding Converter={StaticResource NameGeneration}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</Grid>
</UserControl>
编辑 这是每当打开新 XML 文档时设置新数据源的代码。
var provider = new XmlDataProvider()
{
Source = new Uri(gotFocus.Document.Path + gotFocus.Document.Name),
XPath = "./*"
};
OutlineWindowInstance.TreeItems.DataContext = provider;
顺便说一下,整个 GIT 存储库可以在这里找到: https://github.com/LoganLabster/VsXmlOutline
您不应该在 HierarchicalDataTemplate
中创建另一个 TreeViewItem
容器。尝试定义一个 ItemContainerStyle
来设置 Header
属性:
<TreeView ItemsSource="{Binding Source={StaticResource MyXmlProvider}}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding XPath=./*}" />
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter Property="Header" Value="{Binding Converter={StaticResource NameGeneration}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
感谢@mm8,我找到了答案,一旦我弄明白了,它真的很简单(花了太长时间,doh)。 我没有将 StackPanel 设置为 treeviewitem header,而是在 XAML 中构建了 StackPanel 并一次设置一个值,瞧,它起作用了。
<UserControl x:Class="XmlOutline.OutlineWindowControl"
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:vsshell="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
xmlns:customScripts="clr-namespace:XmlOutline.CustomScripts"
Background="{DynamicResource {x:Static vsshell:VsBrushes.WindowKey}}"
Foreground="{DynamicResource {x:Static vsshell:VsBrushes.WindowTextKey}}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Name="MyToolWindow">
<UserControl.Resources>
<XmlDataProvider x:Key="MyXmlProvider" Source="LogansTest.xml" XPath="/Items"/>
<customScripts:NameGeneration x:Key="NameGeneration"/>
</UserControl.Resources>
<Grid x:Name="TreeGrid" DataContext="MyXmlProvider">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TreeView Name="TreeItems" Visibility="Hidden"
ItemsSource="{Binding}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VirtualizingStackPanel.IsVirtualizing="False"
VirtualizingStackPanel.VirtualizationMode="Standard"
Background="#252525"
SelectedItemChanged="TreeView_OnSelectedItemChanged"
TreeViewItem.Expanded="TreeViewItem_Expanded"
TreeViewItem.Collapsed="TreeViewItem_Collapsed">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate x:Name="myTest" ItemsSource="{Binding XPath=./*}">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="Title" Foreground="LightSkyBlue" FontSize="14"/>
<TextBlock x:Name="SubTitle" Foreground="YellowGreen" FontSize="13"/>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter TargetName="Title" Property="Text" Value="{Binding Path=Name}"/>
<Setter TargetName="SubTitle" Property="Text" Value="{Binding Converter={StaticResource NameGeneration}}" />
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</UserControl>