Могут ли узлы TreeView иметь промежуточные проверенные состояния? - PullRequest
3 голосов
/ 06 января 2010

Вот что я хочу сделать:

  • Представляет набор параметров, разделенных по категориям.
  • Разрешить пользователю отмечать / снимать отметки со всех элементов в категории, устанавливая / снимая отметку с узла категории.
  • Показать, что некоторые параметры в категории проверяются путем установки узла категории в промежуточное проверенное состояние.

Из того, что я прочитал, и из моего ограниченного опыта работы с TreeViews, этот последний желательный вариант не представляется возможным, поскольку узлы TreeNode, похоже, не поддерживают ничего, кроме проверенного состояния включения / выключения. Возможно ли это с помощью TreeView? Есть ли какой-то другой элемент управления, который мог бы это осуществить, или мне придется создать подкласс TreeView, чтобы это сделать?

Ответы [ 4 ]

2 голосов
/ 06 января 2010

Это можно сделать с помощью свойства DrawMode, чтобы вы могли закрасить свой собственный флажок с помощью ControlPaint.DrawCheckBox ().Вам также нужно будет реализовать событие MouseDown и использовать метод HitTest для обнаружения щелчков на фальшивом флажке.Радости нет, но это возможно.

1 голос
/ 27 октября 2011

Можно использовать пользовательский TreeView, поддерживающий три состояния checkBoxes, например this .

0 голосов
/ 31 июля 2014

Это мое решение для 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
0 голосов
/ 06 января 2010

Я думаю, вам придется написать эту функцию самостоятельно. Вы можете сделать это простым и просто закрасить флажок светло-серым или что-то, чтобы показать промежуточное состояние.

Если вы используете WPF, я думаю, вы сможете изменить шаблон элемента управления дерева и / или шаблон элемента управления флажка.

В WPF я бы сказал, что было бы легче реализовать winforms. Не уверен, какую технологию вы используете в этом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...