处理可编辑的分层数据/ TreeView〜DataGrid混合 [英] Handle editable hierarchical data / TreeView~DataGrid hybrid
问题描述
我正在寻找WPF控件,它是TreeView和DataGrid的混合体,类似于Visual Studio调试器或QuickBooks联系人列表等。
I am looking for a WPF control which is a hybrid of TreeView and DataGrid, something like the Visual Studio debugger or QuickBooks contacts list etc.
任何其他解决方案在WPF中如何处理可编辑的分层数据也将非常受欢迎。
Any other solution on how to handle editable hierarchical data in WPF will be very welcommed as well.
推荐答案
在我看来,如果您设计自己的产品,这似乎是一件相当简单的事情
This seems to me like a reasonably straightforward thing to implement if you design your view model properly.
基本上,您可以按照在正常数据网格中显示项目的方式来设计项目,例如,每个项目的每一列都有一个属性。很有可能您的基础数据模型是分层的,但是网格绑定到的集合将被展平,即,将为分层结构中的每个节点包含一个项目,而与父子关系无关。
You basically design the items the same way you would if displaying them in a normal data grid, i.e. each item has a property for each column. In all likelihood, your underlying data model is hierarchical, but the collection that the grid is bound to is going to be flattened, i.e. will contain an item for each node in the hierarchy irrespective of parent/child relationships.
项目视图模型具有一些其他属性:级别
,儿童
, IsExpanded
和 IsVisible
。 Level
是节点祖先的计数, Children
包含子视图模型节点, IsExpanded
用于用户界面,如果节点可见,则 IsVisible
为true。它还实现了称为 VisibleDescendants
的属性:
The item view model has some additional properties: Level
, Children
, IsExpanded
, and IsVisible
. Level
is a count of the node's ancestors, Children
contains the child view model nodes, IsExpanded
is used in the UI, and IsVisible
is true if the node is visible. It also implements a property called VisibleDescendants
:
public IEnumerable<NodeViewModel> VisibleDescendants
{
get
{
return Children
.Where(x => x.IsVisible)
.SelectMany(x => (new[] {x}).Concat(x.VisibleDescendants)));
}
}
您使用 Level 控件第一列中项目样式的code>,
HasChildren
和 IsExpanded
:它们控制
您还需要实现 ExpandCommand
和 CollapseCommand
属性。如果 Children.Any()
为true并且 IsExpanded $ c,则启用
是真的。这些命令在执行后会更改 ExpandCommand
$ c>为false,如果 Children.Any()
为true并且<$ c $为真,则启用 CollapseCommand
c> IsExpanded IsExpanded
的值。
You also need to implement ExpandCommand
and CollapseCommand
properties. The ExpandCommand
is enabled if Children.Any()
is true and IsExpanded
is false, and the CollapseCommand
is enabled if Children.Any()
is true and IsExpanded
is true. These commands, when executed, change the value of IsExpanded
.
这就是有趣的地方。实现此目的的简单方法可能对您有用:父项视图模型公开的项,其 Items
属性不是集合。取而代之的是,它是一个枚举器,沿着子视图模型的链向下移动,并且仅产生可见节点:
And here's where it gets interesting. The simple way to implement this may work for you: the items are exposed by a parent view model whose Items
property is not a collection. Instead, it's an enumerator that travels down the chain of child view models and yields only the visible nodes:
public IEnumerable<NodeViewModel> Items
{
get
{
return _Items
.Where(x => x.IsVisible)
.SelectMany(x => (new[] {x}).Concat(x.VisibleDescendants));
}
}
任何后代 IsVisible
属性更改,父视图模型为 Items
属性引发 PropertyChanged
Whenever any descendant's IsVisible
property changes, the parent view model raises PropertyChanged
for the Items
property, which forces the data grid to repopulate.
也有一个不太简单的实现,您可以将 Items
属性设置为实现 INotifyCollectionChanged
,当后代节点变为可见/不可见时,这会引发适当的 CollectionChanged
事件,但是您只想在性能是一个问题。
There's a less simple implementation too, where you make the Items
property a class that implements INotifyCollectionChanged
, and that raises the proper CollectionChanged
events when descendant nodes become visible/invisible, but you only want to go there if performance is an issue.
这篇关于处理可编辑的分层数据/ TreeView〜DataGrid混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!