TreeView节点是否具有中间检查状态?

以下是我要做的事情:

  • 代表一组选项,按类别划分。
  • 允许用户通过选中/取消选中类别节点来检查/取消选中类别中的所有项目。
  • 显示通过将类别节点设置为中间检查状态来检查类别中的某些选项。

从我读过的内容以及我对TreeViews的有限经验来看,这最后的想法似乎不可能,因为TreeNodes似乎不支持除开/关检查状态之外的任何其他内容。 这可能使用TreeView吗? 是否有一些其他控件可以解决这个问题,或者我是否必须创建一个TreeView子类才能完成它?

它可以通过使用DrawMode属性来完成,因此您可以使用ControlPaint.DrawCheckBox()绘制自己的复选框。 您还必须实现MouseDown事件并使用HitTest方法来检测伪复选框上的点击。 没有很大的快乐,但这是可能的。

您可以使用支持三种状态checkBoxes的自定义TreeView ,例如这一种 。

我想你必须自己写这个function。 您可以保持简单,只需将复选框的颜色设置为浅灰色或显示中间状态即可。

如果您正在使用WPF,我认为您可能能够更改树视图的控件模板和/或复选框的控件模板。

在WPF中我会说实现winforms会更容易。 在这种情况下,不确定您使用的是哪种技术。

这是我在Windows Vista及更高版本中的解决方案:

 Public Structure TV_ITEM Public mask As UInteger Public hItem As IntPtr Public state As UInteger Public stateMask As UInteger  Public pszText As String Public cchTextMax As Integer Public iImage As Integer Public iSelectedImage As Integer Public cChildren As Integer Public lParam As IntPtr End Structure Public Class TreeViewEx Inherits TreeView Private Const TVIF_HANDLE As UInteger = &H10 Private Const TVIF_STATE As UInteger = &H8 Private Const TVIS_STATEIMAGEMASK As UInteger = &HF000 Private Const TV_FIRST As UInteger = &H1100 Private Const TVM_SETITEM As UInteger = TV_FIRST + 13 Private Const TVM_SETEXTENDEDSTYLE As UInteger = TV_FIRST + 44 Private Const TVS_EX_DOUBLEBUFFER As UInteger = &H4 Private Const TVS_EX_PARTIALCHECKBOXES As UInteger = &H80 Private Declare Auto Function SendMessage Lib "user32" (ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByRef lParam As TV_ITEM) As IntPtr Private Declare Auto Function SendMessage Lib "user32" (ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByRef lParam As IntPtr) As IntPtr Private Function INDEXTOSTATEIMAGEMASK(i As Integer) As Integer Return i << 12 End Function Protected Overrides Sub OnHandleCreated(e As System.EventArgs) Dim style As UInteger = TVS_EX_DOUBLEBUFFER Or TVS_EX_PARTIALCHECKBOXES SendMessage(Me.Handle, TVM_SETEXTENDEDSTYLE, New IntPtr(style), New IntPtr(style)) MyBase.OnHandleCreated(e) End Sub Public Sub SetNodeCheckState(node As TreeNode, state As CheckState) If state = CheckState.Indeterminate Then If System.Environment.OSVersion.Version.Major >= 6 Then Dim it As TV_ITEM = Nothing it.mask = TVIF_HANDLE Or TVIF_STATE it.hItem = node.Handle it.stateMask = TVIS_STATEIMAGEMASK it.state = INDEXTOSTATEIMAGEMASK(3) 'indeterminate SendMessage(Me.Handle, TVM_SETITEM, IntPtr.Zero, it) Else node.Checked = False End If Else node.Checked = (state = CheckState.Checked) End If End Sub End Class