Treeview увеличивает прорисовку, но некоторые изменения не распространяются на экран - PullRequest
1 голос
/ 04 августа 2020

Я работаю с древовидной структурой в VB с OwnerDrawText в качестве режима рисования. Я обработал Me.DrawNode в моем древовидном представлении, чтобы позволить мне выделить c элементов (ie сохранить выделенным последний узел и так далее). Я видел, как вызывается вытяжной узел, и попытался установить для всех его фонов заказной цвет, сделав это

Public Class Form1
    Private nodelist As New List(Of TreeNode)

    Public Sub New()
        InitializeComponent()
        TreeView1.Nodes.AddRange(New TreeNode() {
            New TreeNode("Text of Node 0") With {.Name = "Node0"},
            New TreeNode("Text of Node 1") With {.Name = "Node1"},
            New TreeNode("Text of Node 2") With {.Name = "Node2"},
            New TreeNode("Text of Node 3") With {.Name = "Node3"},
            New TreeNode("Text of Node 4") With {.Name = "Node4"}
        })
    End Sub

    Private Sub myTreeView_DrawNode(ByVal sender As Object, ByVal e As DrawTreeNodeEventArgs) Handles TreeView1.DrawNode
        Console.WriteLine(e.Node.Text & " Rewritten")

        ' Draw the background and node text for a selected node.
        If nodelist.Contains(e.Node) Then
            e.Graphics.FillRectangle(New SolidBrush(Color.Chartreuse), e.Bounds)
            TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds,
                                  Color.Black, Color.Empty,
                                  TextFormatFlags.VerticalCenter)
        Else
            e.Graphics.FillRectangle(New SolidBrush(Color.Black), e.Bounds)
            TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds,
                                  Color.White, Color.Empty,
                                  TextFormatFlags.VerticalCenter)
        End If
    End Sub

    Private Sub myTreeView_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles TreeView1.MouseDown
        Console.WriteLine("Clicked")
        Dim clickedNode As TreeNode = TreeView1.GetNodeAt(e.X, e.Y)
        nodelist.Add(clickedNode)
        If nodelist.Count > 3 Then
            nodelist.RemoveAt(0)
        End If
        TreeView1.SelectedNode = clickedNode
    End Sub
End Class

Этот код должен выделить три последних выбранных узла. Однако, если вы щелкните весь узел, от 0 до 5, вы увидите, что он выделяет все. Затем, если вы выберете узел 2, вы увидите, что все узлы перерисованы (Console.WriteLine показано), что, как я предполагаю, будет означать, что узлы 1 и 2 должны потерять цвет выделения, но это не так.

1 Ответ

0 голосов
/ 05 августа 2020

Часть рисования верна, хотя ее можно упростить: одни и те же методы могут использоваться как для фона, так и для визуализации текста, DRY до кода.

Logi c в событии MouseDown требует частичного рефакторинга, поэтому выбранные и невыбранные узлы фактически добавляются и удаляются из коллекции узлов, поля nodelist.

TreeView также должен быть уведомлен об изменении, вызывая его метод Invalidate(), чтобы элемент управления мог перерисовать новый выбор узлов (Invalidate() вызывает элемент управления для перерисовки себя, вызывая его Paint или аналогичное связанное событие: в данном случае событие DrawNode).

Упрощенный метод рисования:

► Примечание: здесь я Я использую e.Node.Bounds как ограничивающий прямоугольник как для фона, так и для текста узла. Вместо него можно использовать e.Bounds, если прямоугольник кажется слишком узким в реальной реализации. Для тестирования (в данном случае это можно рассматривать как вопрос предпочтения).

Private Sub TreeView1_DrawNode(sender As Object, e As DrawTreeNodeEventArgs) Handles TreeView1.DrawNode
    Console.WriteLine(e.Node.Text & " Rewritten")

    Dim backColor As Color = Color.Black
    Dim foreColor As Color = Color.White
    If nodelist.Contains(e.Node) Then
        backColor = Color.Chartreuse
        foreColor = Color.Black
    End If

    e.Graphics.FillRectangle(New SolidBrush(backColor), e.Node.Bounds)
    TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Node.Bounds,
                          foreColor, Color.Transparent, TextFormatFlags.VerticalCenter)
End Sub

Событие MouseDown добавляет текущий выбранный узел в коллекцию nodelist, если это еще не сделано там, иначе узел удаляется из коллекции. Другое условие проверяется перед добавлением выбранного узла в коллекцию: коллекция не может содержать более 4 элементов; если коллекция уже полная , выбранный узел не добавляется.

Private Sub myTreeView_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles TreeView1.MouseDown
    Dim clickedNode As TreeNode = TreeView1.GetNodeAt(e.X, e.Y)
    If nodelist.Contains(clickedNode) Then
        nodelist.Remove(clickedNode)
    Else
        If nodelist.Count < 4 Then
            nodelist.Add(clickedNode)
            TreeView1.SelectedNode = clickedNode
        End If
    End If
    TreeView1.Invalidate()
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...