hierarchicaldatatemplate 相关问题

`HierarchicalDataTemplate`是`DataTemplate`的子类,它允许您直接绑定到对象的层次结构

C# WPF 元素的递归重复嵌套层次结构

我已经创建了从 xml 文件层次结构动态填充的树视图,但我遇到了问题。在树视图中,嵌套层次结构是递归重复的,并得到如下结果: 树视图的 XAML 标记: <

回答 1 投票 0

在 DataTemplate 内部使用 TreeView 层次结构和 HierarchicalDataTemplate

我有一个使用 TreeView 的 WPF 应用程序,该 TreeView 内部有多个不同类型的 HierarchicalDataTemplates/DataTemplates,每个模板都包含一个具有特定

回答 1 投票 0

如何从HierarchicalDataTemplate项目中获取TreeViewItem?

我有一个 TreeView,它使用 HierarchicalDataTemplate 来绑定其数据。 它看起来像这样: 我有一个 TreeView,它使用 HierarchicalDataTemplate 来绑定其数据。 看起来像这样: <TreeView x:Name="mainTreeList" ItemsSource="{Binding MyCollection}> <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type local:MyTreeViewItemViewModel}" ItemsSource="{Binding Children}"> <!-- code code code --> </HierarchicalDataTemplate> </TreeView.Resources> </TreeView> 现在,从主窗口的代码隐藏中,我想获取当前选定的TreeViewItem。但是,如果我使用: this.mainTreeList.SelectedItem; selectedItem 的类型为 MyTreeViewItemViewModel。但我想得到“父母”或“绑定”TreeViewItem。我不会将其传递给我的 TreeViewItemModel 对象(甚至不知道如何传递)。 我该怎么做? TreeViewItem item = (TreeViewItem)(mainTreeList .ItemContainerGenerator .ContainerFromIndex(mainTreeList.Items.CurrentPosition)); 不起作用(对我来说),因为使用 HierarchicalDataTemplate 的树视图中的 mainTreeList.Items.CurrentPosition 将始终为 -1。 也没有,因为使用 HierarchicalDataTemplate 的树视图中的 mainTreeList.Items.CurrentItem 将始终为 null。 TreeViewItem item = (TreeViewItem)mainTreeList .ItemContainerGenerator .ContainerFromItem(mainTreeList.Items.CurrentItem); INSTEAD 我必须在路由的 TreeViewItem.Selected 事件中设置最后选定的 TreeViewItem,该事件会冒泡到树视图(TreeViewItem 本身在设计时不存在,因为我们使用的是 HierarchicalDataTemplate)。 可以在 XAML 中捕获事件,如下所示: <TreeView TreeViewItem.Selected="TreeViewItemSelected" .../> 然后可以在事件中设置最后选择的 TreeViewItem,如下所示: private void TreeViewItemSelected(object sender, RoutedEventArgs e) { TreeViewItem tvi = e.OriginalSource as TreeViewItem; // set the last tree view item selected variable which may be used elsewhere as there is no other way I have found to obtain the TreeViewItem container (may be null) this.lastSelectedTreeViewItem = tvi; ... } 来自 Bea Stollnitz 关于此的博客条目,请尝试 TreeViewItem item = (TreeViewItem)(mainTreeList .ItemContainerGenerator .ContainerFromIndex(mainTreeList.Items.CurrentPosition)); 我遇到了同样的问题。 我需要访问 TreeViewItem 以便选择它。 然后我意识到我可以将属性 IsSelected 添加到我的 ViewModel,然后将其绑定到 TreeViewItems IsSelectedProperty。 这可以通过 ItemContainerStyle 来实现: <TreeView> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/> <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> </Style> </TreeView.ItemContainerStyle> </TreeView> 现在,如果我想选择树视图中的某个项目,我只需直接在 ViewModel 类上调用 IsSelected 即可。 希望它对某人有帮助。 TreeViewItem item = (TreeViewItem)(mainTreeList .ItemContainerGenerator .ContainerFromIndex(mainTreeList.Items.CurrentPosition)); gives first item in the TreeView because CurrentPosition is always 0. 怎么样 TreeViewItem item = (TreeViewItem)(mainTreeList .ItemContainerGenerator .ContainerFromItem(mainTreeList.SelectedItem))); 这对我来说效果更好。 受 Fëanor 答案的启发,我尝试让已创建 TreeViewItem 的每个数据项都可以轻松访问 TreeViewItem。 这个想法是向视图模型添加一个 TreeViewItem 类型的字段,也通过接口公开,并且每当创建 TreeView 容器时让 TreeViewItem 自动填充它。 这是通过子类化 TreeView 并将事件附加到 ItemContainerGenerator 来完成的,每当创建 TreeViewItem 时都会记录它。问题包括 TreeViewItem 是懒惰创建的,因此在某些时间可能真的没有可用的。 自从发布这个答案以来,我进一步开发了它并在一个项目中使用了很长时间。到目前为止没有任何问题,除了这违反了 MVVM(但也为您节省了大量简单案例的样板文件)。来源这里。 用法 选择所选项目的父项并将其折叠,确保它位于视图中: ... var selected = myTreeView.SelectedItem as MyItem; selected.Parent.TreeViewItem.IsSelected = true; selected.Parent.TreeViewItem.IsExpanded = false; selected.Parent.TreeViewItem.BringIntoView(); ... 声明: <Window ... xmlns:tvi="clr-namespace:TreeViewItems" ...> ... <tvi:TreeViewWithItem x:Name="myTreeView"> <HierarchicalDataTemplate DataType = "{x:Type src:MyItem}" ItemsSource = "{Binding Children}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> </tvi:TreeViewWithItem> ... </Window> class MyItem : IHasTreeViewItem { public string Name { get; set; } public ObservableCollection<MyItem> Children { get; set; } public MyItem Parent; public TreeViewItem TreeViewItem { get; set; } ... } 代码 public class TreeViewWithItem : TreeView { public TreeViewWithItem() { ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged; } private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e) { var generator = sender as ItemContainerGenerator; if (generator.Status == GeneratorStatus.ContainersGenerated) { int i = 0; while (true) { var container = generator.ContainerFromIndex(i); if (container == null) break; var tvi = container as TreeViewItem; if (tvi != null) tvi.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged; var item = generator.ItemFromContainer(container) as IHasTreeViewItem; if (item != null) item.TreeViewItem = tvi; i++; } } } } interface IHasTreeViewItem { TreeViewItem TreeViewItem { get; set; } } 尝试这样的事情: public bool UpdateSelectedTreeViewItem(PropertyNode dateItem, ItemsControl itemsControl) { if (itemsControl == null || itemsControl.Items == null || itemsControl.Items.Count == 0) { return false; } foreach (var item in itemsControl.Items.Cast<PropertyNode>()) { var treeViewItem = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem; if (treeViewItem == null) { continue; } if (item == dateItem) { treeViewItem.IsSelected = true; return true; } if (treeViewItem.Items.Count > 0 && UpdateSelectedTreeViewItem(dateItem, treeViewItem)) { return true; } } return false; } 我将 William 的递归搜索修改为更紧凑的版本: public TreeViewItem GetTreeViewItemFromObject(ItemContainerGenerator container, object targetObject) { if (container.ContainerFromItem(targetObject) is TreeViewItem target) return target; for (int i = 0; i < container.Items.Count; i++) if ((container.ContainerFromIndex(i) as TreeViewItem)?.ItemContainerGenerator is ItemContainerGenerator childContainer) if (GetTreeViewItemFromObject(childContainer, targetObject) is TreeViewItem childTarget) return childTarget; return null; } 可以通过提供 TreeView 实例的 ItemContainerGenerator 和目标数据对象来调用它: TreeViewItem tvi = GetTreeViewItemFromObject(treeView.ItemContainerGenerator, targetDataObject); 单个 ItemContainerGenerator.ContainerFromItem 或 ItemContainerGenerator.ItemContainerGenerator 调用无法找到与树视图对象关联的 TreeViewItem,因为树视图项控制器和树视图项数据是分离的。 需要创建一个递归函数来使用 ItemContainerGenerator.ContainerFromItem 和 ItemContainerGenerator.ItemContainerGenerator,以便在树视图中定位 TreeViewItem。 示例递归函数可能如下所示: private TreeViewItem GetTreeViewItemFromObject(ItemContainerGenerator container, object tvio) { var item = container.ContainerFromItem(tvio) as TreeViewItem; if (item != null) { return item; } for (int i = 0; i < container.Items.Count; i++) { var subContainer = (TreeViewItem)container.ContainerFromIndex(i); if (subContainer != null) { item = GetTreeViewItemFromObject(subContainer.ItemContainerGenerator, tvio); if (item != null) { return item; } } } return null; } 呼叫者 var target = GetTreeViewItemFromObject(treeView.ItemContainerGenerator, item); 递归函数仅在树视图的 ItemContainerGenerator.Status 为 ContainersGenerated 后才起作用。所以在初始化视图期间,GetTreeViewItemFromObject不起作用。 您是否需要 TreeViewItem 因为您要修改正在显示的内容?如果是这种情况,我建议使用 Style 来更改项目的显示方式,而不是使用代码隐藏,而不是直接修改 TreeViewItem。希望它会更干净。 如果您必须在孩子的孩子中查找项目,您可能必须使用像这样的递归 public bool Select(TreeViewItem item, object select) // recursive function to set item selection in treeview { if (item == null) return false; TreeViewItem child = item.ItemContainerGenerator.ContainerFromItem(select) as TreeViewItem; if (child != null) { child.IsSelected = true; return true; } foreach (object c in item.Items) { bool result = Select(item.ItemContainerGenerator.ContainerFromItem(c) as TreeViewItem, select); if (result == true) return true; } return false; } 这是解决方案。 rtvEsa 是树视图。 HierarchicalDataTemplate 是树视图模板 标签使当前项目真正消耗。这不是选定的项目,它是使用 HierarchicalDataTemplate 的树控件中的当前项目。 Items.CurrentItem 是内部树集合的一部分。 您无法获得许多不同的数据。例如 Items.ParenItem 也是如此。 <HierarchicalDataTemplate ItemsSource="{Binding ChildItems}"> <TextBox Tag="{Binding ElementName=rtvEsa, Path=Items.CurrentItem }" /> 我的 TreeView 模板只有一级标题,所以我发现成功了: foreach (CollectionViewGroup grp in treeView.Items) { string strHeader = (string)grp.Name; TreeViewItem treeViewItem = (TreeViewItem)treeView.ItemContainerGenerator.ContainerFromItem(grp);

回答 12 投票 0

WPF - 访问命令的 TreeViewItem 的根 UserControl DataContext

我正在尝试执行绑定到子 TreeViewItem 的根父 UserControl 的 ViewModel 中存在的命令。这是来自绑定到根 TreeViewItems 的 ContextMenu。 TreeView 代码...

回答 1 投票 0

WPF TreeView HierarchicalDataTemplate - 绑定到具有多个子集合的对象

我正在尝试获取一个 TreeView 来绑定我的集合,以便所有组都显示嵌套组,并且每个组都将显示条目。 我如何使用 HierarchicalDataTemplate 以便 TreeView 处理

回答 4 投票 0

在树状视图中获取所有选定的项目

您好,我有一个treeview哪个itemtemplate是复选框。我想获取所选项目(ischecked = true),我该怎么做?我想在列表中选择所有项目。某些项目可能具有子...

回答 1 投票 0

WPF GetTemplateChild获取Nullrefrence异常

[嗨,我正在构建一个控件,我需要访问后面代码中的复选框,但是我得到的是空错误,这是我的控件 <......>

回答 2 投票 0

如何在Treeview wpf中获取关联的父级

[我们尝试在树状视图中选择子元素时获取直接关联的父元素。父名称绑定了Textblock(名称为Parent)。如何在...

回答 1 投票 0

WPF层次树视图:自引用层次结构和平面源的组合绑定

最近,我对MVVM /绑定/ Entityframework等了解了很多。而且,我一直很努力地工作-我使用VB.NET-并且必须将大多数从C#找到的代码转换为VB.NET;) ,什么是...

回答 1 投票 0

使用LINQ填充ObservableCollection中的数据

我的结构如下。公共类CategoryClass {公共十进制Category_ID {get;组; }公共字符串Category_Name {get;组; } // public System.Nullable ... ...>

回答 3 投票 1

在WPF TreeView中对子对象进行分组

我正在尝试使我的树形视图按相似项将一组相似项分组。为了保持通用性,我的对象层次结构应如下所示:对象对象组#1项目#1(...

回答 4 投票 7

ConverterParameter与Multibinding上的绑定

是否可以在MultiBinding中将Converter绑定添加到ConverterParameter?像这样的东西:

回答 2 投票 9

使用HierarchicalDataTemplate显示结构化数据,而不使用具有列表或子对象集合的父类

我想使用WPF树视图和一个或多个HierarchicalDataTemplates来创建一个树视图,显示按国家,州和位置组织的位置。我正在寻找一个MVVM XAMl解决方案......

回答 1 投票 0

将自定义类作为TreeViewItem添加到TreeView WPF

我有我的TreeView如下所示的场景:MainParent。> - 父...> - Child1 ...> - Child2 ...> - Child3 ...> - Child4 ...> - Child5 ......> Child1_Of_Child5 ...........> Child1(Child1_Of_Child5)....

回答 1 投票 1

将分层对象数据绑定到ListBox

我正在尝试使用WPF中的数据绑定来填充来自对象源的数据的ListBox。源是ObjectDataProvider,其数据从xml文件加载。我读了XML文件,...

回答 1 投票 1

WPF Caliburn Micro Message.Attach不通过HierarchicalDataTemplate冒泡

我正在尝试连接TreeView中的删除按钮,以便它在其直接父视图模型中调用Remove方法。我得到这个异常:System.Exception:'找不到方法删除的目标。'...

回答 1 投票 2

如何对一个集合的连续类似项目进行分组?

考虑以下集合。 True False False False True True False False我想以结构化的方式显示它,例如,在TreeView中。我希望能够在整个团体周围画出边框......

回答 5 投票 2

WPF TreeView - 如何在添加/删除节点后刷新树?

我参考这篇文章:WPF TreeView HierarchicalDataTemplate - 绑定到具有多个子集合的对象并修改树结构,如:Root | __Group | _Entry | ...

回答 3 投票 4

如何将ConverterParameter传递给HierarchicalDataTemplate

除了用于ItemsSource属性的ConverterParameter之外,我有两个相同的HierarchicalDataTemplates:

回答 1 投票 -1

© www.soinside.com 2019 - 2024. All rights reserved.