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

MultiColumnTree

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (45投票s)

2010年7月21日

CPOL

5分钟阅读

viewsIcon

187584

downloadIcon

8750

多列的树形视图

节点文本或子项值支持多行文本。

allowmultiline.JPG

TreeNode 复选框。当您将 MultiColumnTree 对象的 CheckBoxes 属性设置为 true 时,树节点的复选框不会自动出现,它只会在树节点被选中、鼠标悬停时,或者 CheckState 属性的值不是未选中时出现。

checkboxes.JPG

第一列固定。

column0frozen.JPG

第一列按降序排序。

column0sorted.JPG

第二列具有自定义背景绘制。

columncustombackground.JPG

自定义过滤器按钮(在过滤器弹出窗口中)。

columncustomfilter.JPG

列选项弹出窗口。它将显示 EnableHiddenEnableFrozen 属性设置为 true 的列。允许您在运行时隐藏或冻结列。

columnoptions.JPG

自定义工具提示。但是,如果您将 MultiColumnTree 对象上的 NodeToolTip 属性设置为 true,并且树节点具有工具提示标题、工具提示内容或工具提示图像,才会显示工具提示。如果 MultiColumnTree 对象的 FullRowSelect 属性设置为 true,则当鼠标指针悬停在整个节点上时会显示工具提示,否则,只有当鼠标指针悬停在节点文本上时才会显示工具提示。

customtooltip.JPG

MultiColumnTree 对象的 FullRowSelect 属性设置为 true 时的外观。

fullrowselect.JPG

引言

我需要像 listview 那样在树中显示额外的节点。然而,标准的 WinForms 控件中没有这样的控件。因此,我决定自己创建一个。要使此控件完全可用,还需要进行大量改进。

变更

我不再使用 TreeColumn 类。该类已被 ColumnHeader 类取代,因为我将它与我的 ListView 一起使用,并且 TreeNodeItems 属性已被 SubItems 属性取代。

存在与 MultiColumnTree 类相对应的类。

列(ColumnHeader 类)

表示树的列对象。

  • 支持多列。
  • 支持 4 种不同的列大小类型:固定大小、百分比、自动和填充。
  • 支持运行时排序。
  • 支持显示格式化,包括 DateTimeNumericBarCustom。但是,第 0 列的显示格式将被忽略。
  • 当在列格式属性中使用 Bar 时,您还可以指定条形的最小和最大范围。
  • 支持列过滤,基于所使用的列格式进行列过滤。
  • 支持列背景绘制。您可以在此处绘制每列的自定义背景。
  • 两种不同的对齐方式。列标题中文本的对齐方式取决于 TextAlign 属性,而 SubItem 值的对齐方式取决于 ColumnAlign 属性。
  • 支持工具提示。您可以为每列指定工具提示标题、工具提示内容或工具提示图像。

列的新功能

  • 自定义过滤器。启用每列的自定义过滤操作。如果您将 ColumnHeader 类上的 EnableFilteringEnableCustomFilter 属性设置为 true,此功能将出现。自定义过滤器将在 MultiColumnTree 类上引发 ColumnCustomFilter 事件,您可以通过设置 ColumnHeaderCustomFilter 属性来为相关列设置自定义过滤操作。Custom filter 属性具有对 Delegate Function CustomFilterFunction(ByVal value As Object) As Boolean. 的引用类型。
  • 启用冻结和冻结属性(我不知道该如何命名此功能)。就像 Microsoft Excel 中的冻结窗格功能一样。冻结列将显示在未冻结列的第一个顺序及之上。
  • 启用隐藏和可见属性。显示和隐藏列的能力。

节点(TreeNode 类)

表示树的节点对象。以下是额外的行为。

  • 支持每节点的工具提示标题、内容和图像。
  • 支持节点的多行文本。但是,当 MultiColumnTreeAllowMultiline 属性设置为 true 时,多行文本才会显示。
  • SubItems 属性。用于将额外信息设置为 TreeNodeSubItem
  • 我从 ListViewItem 采用的一个属性,UseNodeStyleForSubItems 属性(我在这里为节点更改了名称)。

子项(TreeNode.TreeNodeSubItem 类)

表示 MultiColumnTreeNode 的一个 SubItem。此类具有与 ListViewItem.ListViewSubItem 类相同的行为,并增加了一些附加功能。

  • 支持多行值。
  • PintValueOnBar 属性。当列格式设置为 Bar 时,此属性允许您在条形上方显示值。

集合

有 4 个集合类来支持 MultiColumnTree 类。

  • TreeNodeCollection 类。表示 MultiColumnTree 控件中 TreeNode 对象的集合。
  • TreeNode.TreeNodeSubItemCollection 类。表示 TreeNode 对象中 TreeNode.TreeNodeSubItem 对象的集合。
  • MultiColumnTree.ColumnHeaderCollection 类。表示 MultiColumnTree 控件中 ColumnHeader 对象的集合。
  • MultiColumnTree.CheckedTreeNodeCollection 类。表示 MultiColumnTree 控件中已选中 TreeNode 对象的集合。

缺点

与标准 TreeView 控件相比,有很多缺点(仅是我知道的),我希望能够改进它,或者有人可以帮助改进它。

  • 不支持 ImageList,因此无法用于填充像使用 Win32Api 调用的资源管理器那样的东西。
  • 不支持拖放操作(在我看来,这个因素使此控件非常无用)。

实现

要使用该控件,只需将其从 IDE 的工具箱窗口拖放到设计视图中的窗体上,就像其他控件一样。

要以编程方式向树控件添加列,请使用 Columns.Add 方法。

' Assumes that you have created an instance of MultiColumnTree, for example : tree
Dim aColumn As ColumnHeader = New ColumnHeader      ' Create an instance of ColumnHeader
aColumn.Text = "Column 1"                           ' You can set the other 
                                                    ' properties like this
tree.Columns.Add(aColumn)                           ' Add this column to tree

要向树控件添加节点,请使用 Nodes.Add 方法。要向节点添加其他项以便在树控件中根据其列显示,请使用节点对象上的 Items.Add 方法。

' Adding a node and additional information to tree
Dim aNode As TreeNode = New TreeNode                ' Create an instance of TreeNode
aNode.Text = "Parent Node"                          ' Set another properties of 
                                                    ' the node here
aNode.SubItems.Add("Parent Sub 1")                  ' Add another items to this node here
tree.Nodes.Add(aNode)                               ' Add this node to tree

要将另一个节点添加为现有节点的子节点,请使用节点对象上的 Nodes.Add 方法。

' Adding a node and additional information to an existing node. For example : aNode
Dim childNode As TreeNode = New TreeNode      ' Create an instance of TreeNode
childNode.Text = "Child Node"                 ' Set another properties of this node here
childNode.Items.Add("Child Sub 1")            ' Add another items to this node here
aNode.Nodes.Add(childNode)                    ' Add this node to aNode

创建列(索引为 1)背景的自定义绘制示例。

' tree.BackgroundColumnPaint event handler
' On e (ColumnBackgroundPaintEventArgs) parameter, it has 4 fields :
' Column, column to be painted.
' ColumnIndex, index of the column in MultiColumnTree.Columns collection.
' Graphics, graphis object used to paint.
' Rectangle, rectangle in which to paint.
Private Sub tree_BackgroundColumnPaint(ByVal sender As Object, _
	ByVal e As ColumnBackgroundPaintEventArgs) Handles tree.BackgroundColumnPaint
    If e.ColumnIndex = 1 Then
        Dim aBrush As LinearGradientBrush = New LinearGradientBrush_
	(e.Rectangle, Color.White, Color.LightBlue, LinearGradientMode.Horizontal)
        e.Graphics.FillRectangle(aBrush, e.Rectangle)
        aBrush.Dispose()
    End If
End Sub

处理 MultiColumnTree 对象上的 ColumnCustomFilter 事件。

' tree.ColumnCustomFilter event handler
Private Sub tree_ColumnCustomFilter(ByVal sender As Object, _
    ByVal e As Ai.Control.ColumnCustomFilterEventArgs) Handles tree.ColumnCustomFilter
    ' Perform your custom filter dialog here.
    ' If you want to cancel the operation, set e.CancelFilter to true.
    ' Add your custom filtering like this.
    e.Column.CustomFilter = AddressOf column1CustomFilter
End Sub
' A function that have matching parameter and return types with 
' Delegate Function CustomFilterFunction(ByVal value As Object) As Boolean
Private Function column1CustomFilter(ByVal value As Object) As Boolean
    ' This is just a sample, to perform custom filtering operation on specified column.
    ' Return true if the value is meet your custom filter parameter, false otherwise.
    Return True
End Function

我收到了一些来自他人的 bug 报告,并且(希望如此,因为我独自一人工作,无法完全测试此控件)已得到修复。

  • 编辑后标签丢失的 bug。
  • 当您将 CheckBoxes 属性设置为 true 时,复选框不会自动出现,当节点 CheckState 不是未选中,或者鼠标指针悬停在节点上,或者节点被选中时,它才会出现。
  • 我使用 Tab 控件创建了我的测试项目,在页面 1 上放置了一个 Button,在页面 2 上放置了 MultiColumnTree 控件,并且可以在 Button 点击事件中填充 MultiColumnTree 控件中的节点。

这是我的更新,很抱歉花了这么长时间。

© . All rights reserved.