我有一个带有树视图和文本框的应用程序:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="550" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TreeView Width="500" Height="500" Name="TestTreeView">
</TreeView>
<TextBox Grid.Row="1"></TextBox>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
在应用程序的构造函数中,我生成1000个项目,每个项目有1个子项目并将其添加到TreeView:
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 1000; i++)
{
TreeViewItem item = new TreeViewItem();
item.Header = "Hey there " + i.ToString();
TreeViewItem subItem = new TreeViewItem();
subItem.Header = "Hi there";
item.Items.Add(subItem);
TestTreeView.Items.Add(item);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的场景中,我选择TreeView的第二项,然后单击进入TextBox以使焦点远离TreeView.然后我用鼠标向下滚动TreeView,将所选项目从视口中移出.然后我扩展另一个项目而不选择它.我的预期结果是我的滚动停留在当前位置,但是它将所选项目滚动到视图中,导致我丢失了我正在扩展的项目.
如果TreeView已经具有焦点,则不会发生这种情况.如果我要选择一个项目,然后向下滚动并展开另一个项目,则不会发生这种跳回所选项目的行为.
这是正常的行为吗?例如,如果我在Visual Studio的解决方案资源管理器中执行这些相同的选择步骤,我就不会遇到这种行为.有没有办法告诉它不要回滚到这样的选定项目?
我知道我可以简单地将RequestBringIntoView的e.Handled设置为true,但是我给出的示例只是对我的问题的一个简单解释.这是我在一个更大的应用程序中使用的TreeView问题的一个例子,我希望在某些条件下将项目带入视图.
我正在尝试使用条件模板设置IsExpanded我的TreeView项目的属性,在XAML:
<DataTrigger Binding="{Binding MyStatus}" Value="Opened">
<Setter TargetName="MyTextBlock" Property="Foreground" Value="Green"/>
<Setter Property="TreeViewItem.IsExpanded" Value="True" />
</DataTrigger>
Run Code Online (Sandbox Code Playgroud)
当我MyStatus从C#代码设置属性时,颜色会更改(因此DataTrigger工作),但节点不会展开.
_myItems[0].MyStatus = MyStatus.Opened;
Run Code Online (Sandbox Code Playgroud)
如何设置TreeViewItem.IsExpanded属性DataTrigger?
当我启动应用程序时,颜色已正确设置,但绿色节点未展开:

而改变的值之后_myItems[0].MyStatus和_myItems[1].MyStatus,颜色也会随之改变,但绿点仍然没有展开.

完整的代码有点长,但它是90%的样板.
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="150" Width="250">
<DockPanel>
<DockPanel.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}" x:Key="MyTemplate">
<StackPanel Orientation="Horizontal">
<!-- ... -->
<TextBlock x:Name="MyTextBlock" Foreground="Green" Text="{Binding Name}" />
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding MyStatus}" Value="Closed">
<Setter TargetName="MyTextBlock" Property="Foreground" Value="Red"/>
<Setter Property="TreeViewItem.IsExpanded" Value="False" />
</DataTrigger>
<DataTrigger Binding="{Binding …Run Code Online (Sandbox Code Playgroud) 嗨我遇到的问题是我有多个TreeView控件,每个TreeView都有自己的TreeViewItem样式,设置它
TreeView ItemContainerStyle ="{StaticResource Style1}"
只会设置根元素而不是所有子元素,如何将样式应用于TreeView中的所有子元素
我的一些TreeViewItems是可点击的,有些则不是.
对于那些不可点击的,我将前景颜色更改为灰色.
但是,如果该项目有子项,我还想将小三角形子弹更改为灰色.
我怎么能这样做,像这样:
//PSEUDO-CODE:
<TreeViewItem IconBulletEnabled="False" IconBulletColor="#aaa" Header="Part 1"/>
Run Code Online (Sandbox Code Playgroud)
听起来很简单?我有一个TreeView,我希望在扩展其中一个节点时发生一些事情.我正在使用MVVM,因此'something'是ViewModel中的命令.
好吧,我发现它毕竟不是那么简单.我环顾四周,尝试了一些事情.例如,使用MVVM Light的EventToCommand:
<i:Interaction.Triggers>
<i:EventTrigger EventName="TreeViewItem.Expanded">
<cmd:EventToCommand Command="{Binding Path=FolderNodeToggledCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Run Code Online (Sandbox Code Playgroud)
此代码(基于此和此)不起作用(没有触发;命令绑定在ViewModel中,但在展开节点时永远不会触发相应的方法).我也试过替换cmd:EventToCommand,i:InvokeCommandAction结果是一样的.第二个链接中的"解决方案"显然有点过分,我不想更改ToggleButton,因为我想使用具有自己的ToggleButton 的WPF TreeView WinForms Style.第二个链接中的第二个答案表明我可能正在尝试在TreeView上使用不存在的事件.
另一种可能的解决方案是绑定TreeViewItem的IsExpanded属性.但是我想将我绑定的对象保持为干净的DTO并在ViewModel中执行操作,而不是在绑定的对象中执行.
那么当TreeViewItem扩展时,如何在ViewModel中调用命令呢?
我在我现在正在处理的应用程序上注意到了这一点,因此我创建了一个简单的测试应用程序来演示。下面是我的一个窗口和树视图项的事件处理程序。如果您展开“一个”或“两个”父节点,并单击其中一个子节点,则在对文本框调用 Focus() 方法后,选定的子节点不会显示为已选择。相反,选择会弹出到父节点。有没有人知道如何克服这个问题,并将选择保留在选定的子节点上?谢谢。
<Window
x:Class="DockingSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
WindowState="Maximized"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TreeView Margin="6">
<TreeViewItem Header="One">
<TreeViewItem Header="One" Selected="TreeViewItem_Selected" />
<TreeViewItem Header="Two" Selected="TreeViewItem_Selected" />
<TreeViewItem Header="Three" Selected="TreeViewItem_Selected" />
</TreeViewItem>
<TreeViewItem Header="Two">
<TreeViewItem Header="One" Selected="TreeViewItem_Selected" />
<TreeViewItem Header="Two" Selected="TreeViewItem_Selected" />
<TreeViewItem Header="Three" Selected="TreeViewItem_Selected" />
</TreeViewItem>
</TreeView>
<TextBox Grid.Column="1" x:Name="textbox" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
{
textbox.Focus();
}
Run Code Online (Sandbox Code Playgroud)
使用上面的窗口和“Selected”事件句柄
我正在合并在互联网上找到的两个例子.一个是关于拉伸的选择样式,另一个是关于树视图中的多选.
除了树视图的缩进外,我还能正常工作.我可以提供所有代码,但这不会解决它.
我的问题在于以下方法:
public static class TreeViewItemExtensions
{
public static int GetDepth(this TreeViewItem item)
{
FrameworkElement elem = item;
while (elem.Parent != null)
{
var tvi = elem.Parent as TreeViewItem;
if (tvi != null)
return tvi.GetDepth() + 1;
elem = elem.Parent as FrameworkElement;
}
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
此方法尝试检索树中treeviewItem的深度.问题是:elem.Parent始终为空.其结果深度为0.
我认为这种情况正在发生,因为我正在使用HierarchicalDataTemplate.我的xaml的一部分看起来像这样.
<TreeView Name="folderTree"
ItemsSource="{Binding Folders}"
SelectedItemChanged="folderTree_SelectedItemChanged"
HorizontalContentAlignment="Stretch">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Folders}"
DataType="{x:Type Model:IFolder}">
<StackPanel Orientation="Horizontal">
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
<DataTrigger …Run Code Online (Sandbox Code Playgroud) 我创建了一个简单的依赖属性,我想将其附加到 TreeViewitem,我对其他控件(例如按钮)做了类似的事情,但无法弄清楚如何在树视图中使用 TreeViewItem 而不丢失我定义的样式。通过下面的代码,我得到“用于类型‘ErrorTreeViewItem’的样式不能应用于类型‘TreeViewItem’。”
public class ErrorTreeViewItem : TreeViewItem
{
static ErrorTreeViewItem()
{
}
public bool ErrorState
{
get { return (bool)GetValue(ErrorStateProperty); }
set { base.SetValue(ErrorStateProperty, value); }
}
public static readonly DependencyProperty ErrorStateProperty =
DependencyProperty.Register("ErrorState", typeof(bool), typeof(ErrorTreeViewItem), new UIPropertyMetadata(false));
}
Run Code Online (Sandbox Code Playgroud)
我的树视图的样式如下所示:
<Style TargetType="me:ErrorTreeViewItem">
<Style.Resources>
...
</Style.Resources>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
...
</Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)
我使用它的方式如下:
<TreeView Name="ApplicationTree" ItemsSource="{Binding Applications}" HorizontalContentAlignment="Stretch" Background="#E8E8E8" >
<TreeView.ItemContainerStyle>
<Style TargetType="me:ErrorTreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" …Run Code Online (Sandbox Code Playgroud) 我想调整默认的 WPF TreeView/TreeViewItem 模板,以便可以突出显示整行,如图所示:

但是,我尝试了谷歌搜索中的几个模板,但没有一个可以真正产生效果,一些错误的答案甚至被标记为正确......
代码流中有一个答案似乎有效,但它添加了额外的 C# 代码,或者不需要额外的代码但工作不完美。
我不想添加额外的 C# 代码,而只想更改默认模板。有人有什么好主意吗?
非常感谢!
- - 编辑 - -
@Nick,使用您的模板后,显示如下,
首先,它没有突出显示“整个”行,“整个”是指树的最宽宽度。
其次,它突出了包括儿童在内的其他领域。

问题:如何在 tkinter.ttk.Treeview 中创建一个节点,其中节点的切换箭头被定义的图像替换?也就是说,我如何从第二张图片转到第一张图片,如下所示。
问题:新墨西哥技术指南显示tkinter.ttk.Treeview可以创建文件夹目录,如下所示:
使用带有“image”关键字的 tkinter.ttk.Treeview .insert() 方法,我只能实现以下目标。图像确实出现在节点文本的左侧,但该图像不会替换切换节点的打开和关闭以显示其后代的箭头。我假设由“image”关键字定义的图像将取代切换箭头。但这并没有发生。
测试代码:
import os
import tkinter as tk
import tkinter.ttk as ttk
from PIL import Image, ImageTk
class App(ttk.Frame):
def __init__(self, master, path):
ttk.Frame.__init__(self, master)
self.tree = ttk.Treeview(self)
ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tree.xview)
self.tree.configure(yscroll=ysb.set, xscroll=xsb.set)
self.tree.heading('#0', text='Directory', anchor='w')
abspath = os.path.abspath(path)
i = './icon/Home-icon_16.gif'
self.root_pic = tk.PhotoImage(file=i)
root_node = self.tree.insert('', 'end', text=' Work Folder', open=True, image=self.root_pic)
l1_node = self.tree.insert(root_node, 'end', text='level 1', open=True)
l2_node …Run Code Online (Sandbox Code Playgroud)