65.9K
CodeProject 正在变化。 阅读更多。
Home

适用于 .NET 的高级 TreeView

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (168投票s)

2006年7月10日

4分钟阅读

viewsIcon

1310402

downloadIcon

33955

TreeViewAdv 控件旨在取代标准的 .NET TreeView。它可以执行相同的功能,并提供一系列高级功能,如多选或多列视图。

TreeViewAdv in Multi-Column mode

引言

在从事几个不同的项目时,我需要显示和编辑分层数据。当然,您首先会想到使用标准的 .NET TreeView 控件。如果只需要基本功能,它工作得相当好。但是,要让这个控件执行更复杂的操作并不容易。我找不到一个免费且完全满足我需求的替代 TreeView 控件,所以最终我决定自己写一个。

这个控件的架构主要源自 Java Swing 组件,并进行了一些修改。以下是 TreeViewAdv 控件的关键功能:

  • 模型-视图架构 - 将在本文的单独部分介绍。
  • 多选 - 标准 TreeView 的第一个限制可能是它不允许选择多个节点。
  • 每个节点无限数量的控件 - 您可以显示三个图标 + 一个 CheckBox + 两个 Label
  • 多列 - 您可以将 TreeView 分割成多个列。
  • 按需加载 - 子节点的延迟加载。
  • 拖放高亮 - 动态高亮放置位置。
  • 100% 纯 .NET 代码 - 此控件不使用 WinAPI。

以下屏幕截图展示了 TreeViewAdv 的功能

Drag&Drop highlighting

Multiselection

Using ComboBox to edit node

模型-视图架构

我非常喜欢模型-视图模式,并决定在这个控件中使用它。该模式的主要思想是将模型(业务对象)与其可视化(控件)分离。如果模型发生更改,它会通过触发相应的事件来通知视图。视图在需要时向模型请求详细信息,并显示更改。模型由 ITreeModelInterface 描述。

public interface ITreeModel
{
    IEnumerable GetChildren(TreePath treePath);
    bool IsLeaf(TreePath treePath);

    event EventHandler<TreeModelEventArgs> NodesChanged; 
    event EventHandler<TreeModelEventArgs> NodesInserted;
    event EventHandler<TreeModelEventArgs> NodesRemoved; 
    event EventHandler<TreePathEventArgs> StructureChanged;
}

它非常简单,您只需要实现两个方法。GetChildren 应该返回指定父节点的子节点列表(根节点为空)。IsLeaf 方法告诉 TreeView 是否应该尝试读取指定父节点的子节点。如果您希望 TreeView 动态跟踪模型更改,您需要使用 ITreeModel 接口的多个事件中的一个。最常见的是 StructureChanged 事件,它会导致 TreeView 完全刷新指定节点(或为空,表示整个模型)。例如,请参阅 ITreeModel 接口的默认实现 – TreeModel 类。

为了指定模型中的确切节点,使用了 TreePath 类。它在 FullPath 属性中存储从根到节点的路径。

public class TreePath
{
    public object[] FullPath{ get; }
    public object LastNode{ get; }
    public object FirstNode{ get; }
}

使用 TreeView

在源代码中,您可以找到两个使用 TreeViewAdv 的示例。最简单的方法是使用 TreeModel。您需要做的就是用数据填充它,并在视图中显示它。

_model = new TreeModel();
_model.Nodes.Add(new Node("Root"));
_tree.Model = _model;

TreeModel 中使用的 Node 类只包含 'Text' 和 'IsChecked' 属性。如果您需要额外的属性,可以创建 Node 类的祖先并在 TreeModel 中使用它。

但是,要充分利用 TreeViewAdv 的强大功能,您应该创建自己的 ITreeModel 接口实现。请参阅源代码中的文件夹浏览器作为示例。

自定义 TreeView

有许多属性有助于自定义 TreeView 的外观和行为。主要属性包括:

  • Model - 将您的模型分配给此属性以显示它。
  • NodeControls - 用于可视化模型的控件集合。您必须提供至少一个 NodeControl 才能看到模型。
  • LoadOnDemand - 在启动时或父节点展开时读取所有子节点。
  • SelectionMode - Single(无多选)、MultiMultiSameParent(只能选择同一节点的子节点)。
  • UseColumns - 是否以列形式显示数据。
  • Columns - 列的集合。对于每列,您可以指定其标题、宽度和对齐方式。

NodeControls

标准的 TreeView 只能为每个节点显示一个图标、一个 CheckBox 和一个 Label。在 TreeViewAdv 中,您可以使用任意数量的 NodeControl。所有控件都必须继承自 'NodeControl' 抽象类。继承的类应包含绘制控件的代码以及响应用户操作的代码 - 鼠标和键盘事件。

NodeControl

这是库提供的所有 NodeControl 的类图

Class diagram

BindableControl 类提供了一个 'DataPropertyName',用于在控件中读取和写入节点的数据。您需要做的就是指定类的属性名称。

条款和条件

TreeViewAdv 控件是免费软件,提供开源代码。只要保留原始版权,您就可以在您的应用程序中使用它。

TreeViewAdv 的最新版本始终可在 此处 找到。请随时在论坛中添加您的评论和建议。

© . All rights reserved.