树视图项是树视图的元素或节点。
我在树视图中有一个树视图项目,该项目将有一个绑定到它的列表: 我在树视图中有一个树视图项目,它将有一个绑定到它的列表: <TreeViewItem Name="tviOffline" Foreground="Red" FontWeight="Bold" Header="Offline"> <TreeViewItem.ItemTemplate> <DataTemplate DataType="{x:Type local:Buddy}"> <StackPanel> <TextBlock Text="{Binding Nick}" FontSize="10" Foreground="#8CFFD528" /> </StackPanel> </DataTemplate> </TreeViewItem.ItemTemplate> </TreeViewItem> 我不知道如何让它的每个孩子都有双击事件。 任何帮助表示赞赏。非常感谢。 <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <EventSetter Event="MouseDoubleClick" Handler="OnItemMouseDoubleClick" /> ... <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <EventSetter Event="MouseDoubleClick" Handler="OnItemMouseDoubleClick" /> ... 然后,必须按如下方式编写处理程序,以防止双击连续的父 TreeViewItems: private void OnItemMouseDoubleClick(object sender, MouseButtonEventArgs args) { if (sender is TreeViewItem) { if (!((TreeViewItem)sender).IsSelected) { return; } } .... do stuff. } 感谢 Aurelien Ribon 完成了 90% 的任务。双击问题在 Stack Exchange 上的其他帖子中似乎是众所周知的。只需将两种解决方案合并为一个答案即可。 这是我设法让它适用于所有情况的唯一方法: void MyTreeView_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) { var clickedItem = TryGetClickedItem(myTreeView, e); if (clickedItem == null) return; e.Handled = true; // to cancel expanded/collapsed toggle DoStuff(clickedItem); } TreeViewItem TryGetClickedItem(TreeView treeView, MouseButtonEventArgs e) { var hit = e.OriginalSource as DependencyObject; while (hit != null && !(hit is TreeViewItem)) hit = VisualTreeHelper.GetParent(hit); return hit as TreeViewItem; } 您需要使用样式设置事件处理程序: <TreeView> <TreeView.Resources> <Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource {x:Type TreeViewItem}}"> <EventSetter Event="MouseDoubleClick" Handler="TreeViewItem_OnMouseDoubleClick"/> </Style> </TreeView.Resources> </TreeView> 通过将样式放入TreeView的资源中,样式将应用于所有项目(而不仅仅是像使用ItemContainerStyle时那样应用于第一级)。 如果用户单击子项,该事件也会在所有父项上引发,因为子项位于其父项内部。因此,您必须在处理程序中过滤事件,以便仅当已单击的元素 (OriginalSource) 位于引发事件的 TreeViewItem 中时才起作用。最后,这是一个冒泡事件,所以如果你不想让事件在层次结构中向上,你需要将 Handled 设置为 true: void TreeViewItem_OnMouseDoubleClick(object sender, MouseButtonEventArgs e) { var senderTreeViewItem = (TreeViewItem)sender; TreeViewItem treeViewItemWhichHasBeenClicked = ((DependencyObject)e.OriginalSource!).GetVisualParentOrDefault<TreeViewItem>()!; if (senderTreeViewItem == treeViewItemWhichHasBeenClicked) { Debug.WriteLine("Do stuff"); e.Handled = true; } } static class DependencyObjectExtensions { public static T? GetVisualParentOrDefault<T>(this DependencyObject depObj) where T : DependencyObject { while (true) { ArgumentNullException.ThrowIfNull(depObj); DependencyObject? parent = VisualTreeHelper.GetParent(depObj); switch (parent) { case null: return null; case T result: return result; default: depObj = parent; break; } } } }
WPF ContextMenuOpening 未在带有 StackPanel 的 TreeViewItem 上触发
在 TreeView 中,我有一个 HierarchicalDataTemplate,TreeViewItem 位于水平 StackPanel 中。 当我右键单击图像或文本块时,会触发 ContextMenuOpening 事件,但是当我...
绑定到 TreeViewItem.IsExpanded 只有一种方式
我有以下控件(摘录) 我有以下控件(摘录) <TreeView x:Name="provenanceTree" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" ItemsSource="{x:Bind ProvenanceTreeItems}" SelectionMode="Single" > <TreeView.ItemTemplate> <DataTemplate x:DataType="local:IProvenance"> <TreeViewItem ItemsSource="{x:Bind Children}" IsExpanded="{x:Bind isExpanded, Mode=TwoWay}"> <!-- The template - not relevant here, I think --> </TreeViewItem> </DataTemplate> </TreeView.ItemTemplate> </TreeView> 当然,我的想法是我希望能够扩展和压缩数据源中的树视图项。 isExpanded 是在 IProvenance 的实现中定义的: public static DependencyProperty isExpandedProperty = DependencyProperty.Register( nameof (isExpanded), typeof (bool), typeof (Expandable), new PropertyMetadata (false)); public bool isExpanded { get=> (bool)GetValue(isExpandedProperty); set => SetValue(isExpandedProperty, value); } 我认为没有什么值得警惕的。 我的问题是双向绑定似乎不起作用。 当新项目添加到树中时,isExpanded中的值将被遵守(正如我可以通过更改属性元数据来显示的那样)。 当我使用 UI 扩展和压缩项目时,isExpanded 会正确更新。 但是,当我在填充树后更改代码中的 isExpanded 时,什么也没有发生。 (值更新正确 - 我在调试器中看到过 - 只是树视图没有改变。) 我找到了这个答案,但我认为它对我没有帮助,因为我使用的是Winui 3(其中HierarchicalDataTemplate不可用,并且样式内部的绑定是有问题的)。 我忘记了什么? 让我向您展示一个在其子项展开时展开的 TreeView 的工作示例: Shell.xaml <Page x:Class="WinUIApp1.Shell" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:WinUIApp1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" mc:Ignorable="d"> <Grid RowDefinitions="Auto,*"> <StackPanel Grid.Row="0" Orientation="Horizontal"> <Button Content="Expanding Test" Click="ExpandingTestButton_Click"/> </StackPanel> <TreeView Grid.Row="1" ItemsSource="{x:Bind Items}"> <TreeView.ItemTemplate> <DataTemplate x:DataType="local:Item"> <TreeViewItem Content="{x:Bind Content}" IsExpanded="{x:Bind IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{x:Bind Children, Mode=OneWay}" /> </DataTemplate> </TreeView.ItemTemplate> </TreeView> </Grid> </Page> Shell.xaml.cs public sealed partial class Shell : Page { public Shell() { InitializeComponent(); AddTestItems(); } public ObservableCollection<Item> Items { get; } = []; private void AddTestItems() { var item1 = new Item("Item 1"); var item1Child1 = new Item("Item 1-1"); var item1GrandChild1 = new Item("Item 1-1-1"); var item1GrandChild2 = new Item("Item 1-1-2"); item1Child1.Children.Add(item1GrandChild1); item1Child1.Children.Add(item1GrandChild2); item1.Children.Add(item1Child1); Items.Add(item1); var item2 = new Item("Item 2"); var item2Child1 = new Item("Item 2-1"); var item2GrandChild1 = new Item("Item 2-1-1"); var item2GrandChild2 = new Item("Item 2-1-2"); item2Child1.Children.Add(item2GrandChild1); item2Child1.Children.Add(item2GrandChild2); item2.Children.Add(item2Child1); Items.Add(item2); } private void ExpandingTestButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { Items[0].IsExpanded = true; //Items[0].Children[0].IsExpanded = true; } } Item.cs public partial class Item : ObservableObject { [ObservableProperty] private bool _isExpanded; public Item(string content) { Content = content; Children.CollectionChanged += Children_CollectionChanged; } public event EventHandler<bool>? IsExpandedChanged; public ObservableCollection<Item> Children { get; } = []; public string Content { get; } private void Children_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null) { foreach (Item child in e.NewItems) { child.IsExpandedChanged += Child_IsExpandedChanged; } } if (e.OldItems != null) { foreach (Item child in e.OldItems) { child.IsExpandedChanged += Child_IsExpandedChanged; } } } private void Child_IsExpandedChanged(object? sender, bool isExpanded) { if (isExpanded is true) { IsExpanded = true; } } partial void OnIsExpandedChanged(bool value) { IsExpandedChanged?.Invoke(this, value); } } 备注 ObservableObject 和 ObservableProperty 来自 CommunityToolkit.Mvvm NuGet 包。
我的树视图定义如下: 我的树视图定义如下: <TreeView x:Name="ProvenanceTree" Grid.Column="0" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" ItemsSource="{x:Bind ProvenanceTreeItems}" SelectionMode="Single" ItemInvoked="ProvenanceTree_ItemInvoked" > <TreeView.ItemContainerStyle> <Style TargetType="TreeViewItem"> <Setter Property="Height" Value="20"/> <Setter Property="MinHeight" Value="10"/> <Setter Property="Margin" Value="0 0 0 0"/> <Setter Property="Padding" Value="0 0 0 0"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderBrush" Value="Red"/> </Style> </TreeView.ItemContainerStyle> <TreeView.ItemTemplate> <DataTemplate x:DataType="local:IProvenance"> <TreeViewItem ItemsSource="{x:Bind Children}" IsExpanded="True"> <Grid Background="{x:Bind HighlightColor.dilutedBrush}" Margin="0 0 0 0" Padding="0 0 0 0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="150"/> <ColumnDefinition Width="Auto" MinWidth="75"/> <ColumnDefinition Width="Auto" MinWidth="30" MaxWidth="100"/> </Grid.ColumnDefinitions> <TextBlock Text="{x:Bind name}" TextTrimming="CharacterEllipsis" ToolTipService.ToolTip="{x:Bind name}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0"/> <TextBlock Text="{x:Bind typeName}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="1"/> <TextBlock Text="{x:Bind annotation}" TextTrimming="CharacterEllipsis" ToolTipService.ToolTip="{x:Bind annotation}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="2"/> </Grid> </TreeViewItem> </DataTemplate> </TreeView.ItemTemplate> </TreeView> 它看起来像这样: 我在这里看到的是:每个 TreeViewItem 都被压缩到 20 像素高,正如它应该的那样。 (红色边框只是为了让我可以看到容器的范围 - 不打算保留它!)但是每个项目周围都有几个像素的背景,并且每个项目之间有几个像素的空间。 理想情况下,我想摆脱多余的空间,并将项目压缩在一起。 我可以增加填充和边距(正如您所期望的那样,填充会增加边框的大小,而边距会增加间距),但将它们设置为零显然不会消除它们,并且将它们设置为负数没有任何作用. 这些最小尺寸是在哪里定义的,有什么方法可以覆盖它们吗? 您可以覆盖 TreeViewItemPresenterPadding 资源。 <TreeView...> <TreeView.Resources> <Thickness x:Key="TreeViewItemPresenterPadding">0</Thickness> </TreeView.Resources> </TreeView> 您可以在 generic.xaml 文件中了解这一点。
搜索并找到TreeItem后,我可以滚动到TreeView中选定的项目吗? (JavaFX)
我有一个 TreeView,其中有许多 TreeItems。我已经构建了一个搜索功能,可以工作并选择指定的 TreeItem,但 TreeView 滚动功能不会滚动到它,因此必须...
问题:如何在 tkinter.ttk.Treeview 中创建一个节点,其中节点的切换箭头被定义的图像替换?也就是说,我如何从第二张图片到第一张图片
我需要根据模型属性更改 TreeViewItem 的 BorderBrush。这是我的代码: 使用系统.Windows; 命名空间 Test_Project { 公共部分类 MainWindow : 窗口 {
如何在 avalonia 中正确展开 TreeViewItem
我有一个带有带数据模板的树视图的用户控件。 我在构造函数中填充树视图,如下所示: var Works = new WorksTreeViewItem(); var world = 新的 WorldTreeViewItem ...
TreeViewItem 上的事件,仅在根 Item 上工作
我是 WPf 的初学者,正在研究 TreeView 和 TreeViewItem。我想将事件添加到每个 TreeViewItem。但是无论我单击 rootitem 还是 childItem,处理程序的发件人始终是根项目。 这是我的...
当项目被添加到绑定的可观察集合时,WPF树形视图可见性转换器不更新。
我建立了一个绑定到可观察集合的树形视图,并在每个树形视图项之间建立了连接线。正在使用的视图模型实现了INotifyPropertyChanged ...
我想在WPF上给树形视图项目添加一个图像图标。我怎么才能做到这一点呢?我正在编写一个树形视图,里面有我所有的电脑文件和文件夹,我想让它更美观一点。我试过:...
我试着用treeeview base one MVVM来学习。我参考了这个教程https:/www.codeproject.comArticles26288Simplifying-the-WPF-TreeView-by-Using-the-ViewMode,它非常有帮助,我试着......
我尝试通过参考Josh的教程https://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode将MVVM应用到树视图中,这是我的完整源代码TreeNode .cs ...
使用{x:Bind}的UWP TreeView HasUnrealizedChildren
我在这里阅读:Microsoft Docs:TreeView,我发现属性HasUnrealizedChildren非常适合我的情况,因为我有一个非常深且非常复杂的TreeStructure。我所拥有的...
[WPF树视图可见性转换器在将项目添加到绑定的可观察集合时不更新
我已经构建了绑定到可观察集合的树视图,并通过每个树视图项之间的连接线来构建它。正在使用的视图模型实现INotifyPropertyChanged ...
使用JavaFx将JSONObject /字符串添加到TreeView
我正在尝试使用JavaFx和SceneBuilder在TreeView中显示JSON文件。我遵循了本教程https://www.geeksforgeeks.org/parse-json-java/来读取JSON文件,但是我遇到了问题...
我正在从字典中填充两级TreeView myFirstDictionary(用于第一级)和从字典 mySecondDictionary(用于第二级):XAML: ]
我正在为我的公司开发WPF应用程序,并且所有内容的外观都应与公司的外观相同。因此,我必须制作一个自定义文件夹资源管理器,该资源管理器将具有...
[我们尝试在树状视图中选择子元素时获取直接关联的父元素。父名称绑定了Textblock(名称为Parent)。如何在...