TreeView节点可以具有中间检查状态吗?

时间:2010-01-06 00:56:03

标签: c# treeview

以下是我要做的事情:

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

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

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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

Public Structure TV_ITEM
    Public mask As UInteger
    Public hItem As IntPtr
    Public state As UInteger
    Public stateMask As UInteger
    <Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.LPTStr)>
    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
相关问题