vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Blitzschnelles Erstellen von grafischen Diagrammen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
OwnerDraw Treeview 
Autor: Manfred X
Datum: 27.05.14 16:03

Ich habe das Video nicht angeschaut, erkenne aber das Problem.
Beim Click auf den Button "btn" werden die gecheckten Nodes gelistet,
aber bei schneller Click-Wiederholung klappt beim Treeview die
Koordination zwischen der Anzeige des Node-Check und zurückgegebenen
Check-Eigenschaft des Node nicht.

Workaround: Eventuell die Knoten selbst zeichen
Public Class frmCheckedNodes
 
    Dim WithEvents trv As New TreeView With _
              {.Parent = Me, .Width = 200, .CheckBoxes = True, _
               .DrawMode = TreeViewDrawMode.OwnerDrawAll}
 
 
    Dim CheckedNodes As New List(Of String)
    Dim bs As New BindingSource With {.DataSource = CheckedNodes}
    Dim lbo As New ListBox With _
        {.Parent = Me, .Left = 210, .Top = 40, .DataSource = bs}
 
    Dim WithEvents btn As New Button With _
        {.Parent = Me, .Left = 210, .Text = "Checked Nodes"}
 
 
    Private Sub frmCheckedNodes_Load(sender As System.Object, _
        e As System.EventArgs) Handles MyBase.Load
 
        FillTree()
    End Sub
 
    Private Sub btn_Click(sender As Object, _
        e As System.EventArgs) Handles btn.Click
 
        CheckedNodes.Clear()
        ListCheckedNodes(trv, CheckedNodes)
        bs.ResetBindings(False)
    End Sub
 
 
    Private Sub HandleMouseDown(ByVal sender As Object, _
         ByVal e As MouseEventArgs) Handles trv.MouseDown
 
        Dim info As TreeViewHitTestInfo = trv.HitTest(e.X, e.Y)
        If (info IsNot Nothing) Then
            info.Node.Checked = Not info.Node.Checked
        End If
    End Sub
 
 
    Private Sub trv_DrawNode(sender As Object, _
        e As System.Windows.Forms.DrawTreeNodeEventArgs) Handles trv.DrawNode
 
        Dim f As Font = e.Node.NodeFont
        If f Is Nothing Then f = trv.Font
 
        Dim c As Color = Color.Black
        If e.Node.Checked Then c = Color.Red
        Using br As New SolidBrush(c)
            e.Graphics.DrawString(e.Node.Text, f, br, e.Node.Bounds.Location)
        End Using
 
    End Sub
 
 
    Private Sub FillTree()
        For i As Integer = 0 To 5
            Dim sn As TreeNode = trv.Nodes.Add(CStr(i), CStr(i))
            For k As Integer = 0 To 5
                sn.Nodes.Add(CStr(i) + CStr(k), CStr(i) & CStr(k))
            Next k
        Next i
    End Sub
 
 
    Private Sub ListCheckedNodes(ByVal trv As TreeView, _
        ByVal lst As List(Of String))
 
        For Each node As TreeNode In trv.Nodes
            If node.Checked Then
                lst.Add(node.FullPath)
            End If
 
            For Each sn As TreeNode In node.Nodes
                CheckedNodesRecursive(sn, lst)
            Next sn
        Next
    End Sub
 
 
    Private Sub CheckedNodesRecursive(ByVal tn As TreeNode, _
         ByVal lst As List(Of String))
 
        If tn.Checked Then
            lst.Add(tn.FullPath)
        End If
 
        For Each sn As TreeNode In tn.Nodes
            CheckedNodesRecursive(sn, lst)
        Next
    End Sub
 
 
End Class


Beitrag wurde zuletzt am 27.05.14 um 16:05:39 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

VB.net Treeview mit Checkboxes - Wie prüfe ich ob TopNode gecheckt wurde 
Autor: Jenpet
Datum: 26.05.14 16:56

Ich habe ein Problem mit vb.net.

Ich kann nicht prüfen, ob der TopNode gechecked wurde, wenn nur der TopNode gecheckt wurde und kein unterordner.

http://www.fotos-hochladen.net/uploads/treeview50sjahpg14.png

Ich habe schon mehrere Beispiele im Internet ausprobiert, aber überall tritt das gleiche Problem bei mir auf.

VB.net behauptet immer Checked = False, obwohl die Checkbox angekreuzt ist (das Bild habe ich beim Debuggen gemacht):

http://www.fotos-hochladen.net/uploads/checkedgujbfzr42w.png

Ich habe mit der Funktion versucht zu prüfen welche Checkboxen angekreuzt sind, um diese später in einen anderen Ordner zu kopieren.


    Private Sub PrintRecursive(ByVal n As TreeNode)
        Dim aNode As TreeNode
        For Each aNode In n.Nodes
            If aNode.Checked Then
                proveChecked = True
                listPath.Add(aNode.FullPath)
                filesCount += My.Computer.FileSystem.GetFiles( _
                  aNode.FullPath).Count
            End If
            PrintRecursive(aNode)
        Next
    End Sub
 
 
    ' Call the procedure using the top nodes of the treeview.
    Private Sub CallRecursive(ByVal aTreeView As TreeView)
        'If aTreeView.TopNode.Checked Then 
        '    proveChecked = True
        '    listPath.Add(aTreeView.TopNode.FullPath)
        'End If
        Dim n As TreeNode
        For Each n In aTreeView.Nodes
            PrintRecursive(n)
        Next
    End Sub
In der unteren Funktion im auskommentierten Bereich habe ich versucht die TopNode zu überprüfen.

Hatte hier auch schon jemand einmal das Problem, dass eine Checkbox gechecked war und das trotzdem nicht erkannt wurde? Mache ich evtl. etwas falsch in der Funktion und man kann es gar nicht auf diese Art prüfen?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Alles in Ordnung ???? 
Autor: Manfred X
Datum: 26.05.14 18:52

  TreeView1.Nodes.Add("Key", "Text")
 
  TreeView1.Nodes.Item("Key").Checked = True
 
  If TreeView1.Nodes.Item("Key").Checked Then
      MsgBox("Alles in Ordnung")
  End If
In Deinem Code wird die oberste Knotenebene nicht geprüft.

Beitrag wurde zuletzt am 26.05.14 um 18:54:24 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: VB.net Treeview mit Checkboxes - Wie prüfe ich ob TopNode gecheckt wurde 
Autor: Manfred X
Datum: 26.05.14 19:54

Vielleicht so etwas ...
(Sollen untergeordnete Knoten geprüft werden, wenn der
übergeordnete Knoten nicht gechecked worden ist?)
    Dim listpath As New List(Of String)
 
    ' Call the procedure using the top nodes of the treeview.
    Private Sub CallRecursive(ByVal aTreeView As TreeView)
        For Each node As TreeNode In aTreeView.Nodes
            If node.Checked Then
                listpath.Add(node.FullPath)
            End If
            Dim n As TreeNode
            For Each n In node.Nodes
                PrintRecursive(n)
            Next n
        Next
    End Sub
 
 
    Private Sub PrintRecursive(ByVal n As TreeNode)
        If n.Checked Then
            listpath.Add(n.FullPath)
        End If
 
        Dim aNode As TreeNode
        For Each aNode In n.Nodes
            PrintRecursive(aNode)
        Next
    End Sub
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: VB.net Treeview mit Checkboxes - Wie prüfe ich ob TopNode gecheckt wurde 
Autor: Jenpet
Datum: 27.05.14 09:08

Danke für den Code, werde ich gleich mal ausprobieren!

Ja untergeordnete Knoten sollen auch geprüft werden. Es soll auch möglich sein nur unterordner zu Kopieren. Wenn ich z.B. nur den letzten Knoten checke, soll der ganze Pfad aufgebaut werden im neuen Ordner, aber die Files sollen nur aus den Ordnern kopiert werden, die gecheckt wurden.
Das Funktioniert schon alles, nur wenn ich die TopNode checke hat es bis jetzt nicht geklappt, dann hat mein Programm so reagiert als hätte ich nichts gecheckt und hat einfach den kompletten Pfad kopiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: VB.net Treeview mit Checkboxes - Wie prüfe ich ob TopNode gecheckt wurde 
Autor: Jenpet
Datum: 27.05.14 11:32

Als ich Manfreds Code gerade ausprobiert habe und es einmal ging und dann wieder nicht, ist mir aufgefallen, dass das Problem gar nicht am Code liegt, sondern an der Treeview.

Ich habe davon ein Video gemacht:
http://www.vidup.de/v/618Bh/
(das Passwort lautet vb.net)

Wenn man mehrmals schnell auf den Knoten Test2 klickt und so nur dieser gecheckt ist und alle anderen nicht, erkennt VB.net das nicht als checked an.
Im Video wird das dann so gehandhabt, als ob ich nichts angeklickt hätte und der komplette Ordner wird kopiert.

Beim 2. mal im Video ab Sekunde 7 klicke ich einmal auf den Knoten Test2 und entferne die hinteren gecheckten Knoten in dem ich den nächsten Knoten Test3 wegklicke. Hier wird dann wirklich nur alles was sich in Test2 befindet kopiert, so wie es auch sein sollte.

Ich habe versucht dieses Event zu verhindern, in dem ich einfach beim Doppelklick sage, entferne alle checks.

    Private Sub TreeView1_DoubleClick(sender As Object, e As System.EventArgs) _
      Handles TreeView1.DoubleClick
        'Me.TreeView1.SelectedNode.Checked = True
        UncheckAllNodes(TreeView1.Nodes, False)
    End Sub
Und da das Treenode auch selektiert wird, sage ich entferne alle Selektierungen.

    Private Sub TreeView1_AfterSelect(ByVal sender As Object, _
    ByVal e As TreeViewEventArgs) _
    Handles TreeView1.AfterSelect
        'If e.Node.Nodes.Count = 0 Then
        '    AllSubDirectories(e.Node)
        'End If
        TreeView1.SelectedNode = Nothing
    End Sub
Trotzdem tritt das Problem immer noch auf und ich will verhindern, dass ein Benutzer per Mehrfachklick den Knoten checkt und dann alles kopiert wird, statt nur dem Ordner der wiklich kopiert werden soll.

Da das für mich die 2 Events waren, mit denen ich das fehlerhafte Checken ausführe, habe ich es damit probiert. Könnten es evtl. noch andere Events sein die Schuld daran sind, dass der Knoten gecheckt ist, obwohl er für VB.net nicht gecheckt ist?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: VB.net Treeview mit Checkboxes - Wie prüfe ich ob TopNode gecheckt wurde 
Autor: Jenpet
Datum: 28.05.14 09:15

Danke für den Tipp, die Checks per Button selbst auszuwählen würde zu lange dauern.

Die Ordner die kopiert werden müssen, sind viele GB groß und von den 100 Ordnern werden im Schnitt 5-15 nicht gebraucht beim kopieren, je nachdem bei wem man das durchführt.

Eigentlich wäre die Lösung die ich erstellt habe genau so wie wir es brauchen, wenn dieses Koordinationsproblem zwischen Anzeige und den Eigenschaften gibt. Gleich der erste den ich mein Programm hab testen lassen, bei dem ist sofort dieses Problem aufgetreten.

Aber danke für die Tipps.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Zeichenschule: CheckedTreeview 
Autor: Manfred X
Datum: 28.05.14 11:05

Probier mal diese Ableitung des Treeview.
Imports System.Windows.Forms
 
Public Class CheckedTreeView
    Inherits TreeView
 
    Public Sub New()
        MyBase.DrawMode = TreeViewDrawMode.OwnerDrawAll
        MyBase.CheckBoxes = True
    End Sub
 
 
 
    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
 
        Dim info As TreeViewHitTestInfo = Me.HitTest(e.X, e.Y)
        If info IsNot Nothing AndAlso info.Node IsNot Nothing Then
            If e.X < info.Node.Bounds.X + info.Node.Bounds.Width + 4 Then
                'Click auf die Checkbox Checked oder unchecked
                info.Node.Checked = Not info.Node.Checked
            Else
                'Click auf den Node-text collapsed oder expand
                If info.Node.IsExpanded Then
                    info.Node.Collapse()
                Else
                    info.Node.Expand()
                End If
            End If
        End If
    End Sub
 
 
 
    Protected Overrides Sub OnDrawNode _
        (e As System.Windows.Forms.DrawTreeNodeEventArgs)
 
        MyBase.OnDrawNode(e)
 
        With e.Node
            Dim f As Font = .NodeFont
            If f Is Nothing Then f = Me.Font
 
            Dim c As Color = .ForeColor
            If .Checked Then c = Color.Red
            If c.A = 0 Then c = Me.ForeColor 'Knotenfarbe nicht definiert
 
            Using brfore As New SolidBrush(c), _
                brback As New SolidBrush(.BackColor), _
                p As New Pen(c, 1), _
                brTreeBack As New SolidBrush(Me.BackColor)
 
                With .Bounds
                    'Treeview Knotenhintergrund zeichnen
                    Dim nodespacerect As New Rectangle _
                        (Me.Left, .Y, Me.Width, .Height)
 
                    e.Graphics.FillRectangle(brTreeBack, nodespacerect)
 
                    'Checkbox für Knoten zeichnen
                    Dim box As New Rectangle _
                       (.X + 2, .Y + 2, .Height - 4, .Height - 4)
 
                    e.Graphics.DrawRectangle(p, box)
 
                    If e.Node.Checked Then
                        'Checkbox markieren
                        e.Graphics.DrawLine _
                              (p, .X, .Y, .X + .Height, .Y + .Height)
                        e.Graphics.DrawLine _
                              (p, .X + .Height, .Y, .X, .Y + .Height)
                    End If
 
                    'Text ausgeben (incl. Expand/Collapse-Zeichen)
                    If e.Node.Nodes.Count = 0 Then
                        e.Graphics.DrawString _
                          (e.Node.Text, f, brfore, .X + .Height + 4, .Y)
                    Else
                        'Unterknoten: kollabiert oder expandiert?
                        Dim cs As String
                        If e.Node.IsExpanded Then cs = "(-) " Else cs = "(+) "
 
                        e.Graphics.DrawString _
                           (cs & e.Node.Text, f, brfore, .X + .Height + 4, .Y)
                    End If
 
                    'ggf. Verbindungslinie zum übergeordneten Knoten zeichnen
                    If e.Node.Parent IsNot Nothing Then
 
                        Dim start As Integer = _
                            e.Node.Parent.Bounds.X + Fix(.Height \ 2)
 
                        e.Graphics.DrawLine _
                           (p, New Point(start, .Y + .Height \ 2), _
                            New Point(.X - 4, .Y + .Height \ 2))
 
                        e.Graphics.DrawLine _
                           (p, New Point(start, .Y + .Height), _
                            New Point(start, e.Node.Parent.Bounds.Y + _
                            e.Node.Parent.Bounds.Height))
                    End If
                End With
            End Using
        End With
    End Sub
 
    ''' <summary>Modus, in dem Nodes gezeichnet werden (OwnerDrawAll)</summary>
    Public Shadows ReadOnly Property Drawmode() As TreeViewDrawMode
        Get
            Return MyBase.DrawMode
        End Get
    End Property
 
    ''' <summary>zu jedem Knoten wird ein Kontrolkästchen angezeigt</summary>
    Public Shadows ReadOnly Property Checkboxes() As Boolean
        Get
            Return MyBase.CheckBoxes
        End Get
    End Property
End Class


Beitrag wurde zuletzt am 28.05.14 um 11:10:48 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: VB.net Treeview mit Checkboxes - Wie prüfe ich ob TopNode gecheckt wurde 
Autor: Jenpet
Datum: 28.05.14 15:29

Sorry für die Frage, aber ich hab seit sicher 3-4 Jahren nix mehr mit Vererbungen gemacht und damals war das noch mit C++.

Ich hab die Klasse CheckedTreeView erstellt und ein Objekt davon in meiner Form1.VB erstellt.

Benutze ich jetzt jedesmal das Objekt der Klasse CheckedTreeView statt meinem orginal TreeView1 Objekt oder benutze ich nur im Load-Bereich das CheckedTreeView Objekt, um das alles zu zeichnen?

Und falls ich jedesmal das neue Objekt benutze, rufe ich es in den Events auf oder funktioniert das so nicht?

Wahrscheinlich ist das eher eine Frage für den Anfängerbereich, aber da hänge ich gerade etwas fest
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Es geht voran .... 
Autor: Manfred X
Datum: 28.05.14 15:42

Imports System.Windows.Forms
 
Public Class CheckedTreeView
    Inherits TreeView
 
 
    Public Sub New()
        MyBase.DrawMode = TreeViewDrawMode.OwnerDrawAll
        MyBase.CheckBoxes = True
    End Sub
 
 
    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
 
        Dim info As TreeViewHitTestInfo = Me.HitTest(e.X, e.Y)
        If info IsNot Nothing AndAlso info.Node IsNot Nothing Then
            With info.Node
                If e.X > .Bounds.X - 2 And _
                    e.X < .Bounds.X + .Bounds.Height + 4 Then
                    'Click auf die Checkbox: Checked oder unchecked
                    .Checked = Not .Checked
                Else
                    'Click auf den Node-text: collapsed oder expand
                    If .IsExpanded Then
                        .Collapse()
                    Else
                        .Expand()
                    End If
                End If
            End With
        End If
    End Sub
 
 
    Protected Overrides Sub OnDrawNode _
        (e As System.Windows.Forms.DrawTreeNodeEventArgs)
 
        MyBase.OnDrawNode(e)
 
        Dim checkedcolor As Color = Color.Red
 
        If e.Node.Bounds.Y = 0 And _
            Not Me.Nodes(0) Is e.Node Then Exit Sub 'Bug abfangen
 
        With e.Node
 
            Dim f As Font = .NodeFont
            If f Is Nothing Then f = Me.Font
 
            Dim c As Color = .ForeColor
            If .Checked Then c = checkedcolor
            If c.A = 0 Then c = Me.ForeColor 'Knotenfarbe nicht definiert
 
            Using brfore As New SolidBrush(c), _
                brback As New SolidBrush(.BackColor), _
                p As New Pen(c, 1), _
                brTreeBack As New SolidBrush(Me.BackColor)
 
                With .Bounds
 
                    'Checkbox für Knoten zeichnen
                    Dim box As New Rectangle _
                       (.X + 2, .Y + 2, .Height - 4, .Height - 4)
 
                    e.Graphics.DrawRectangle(p, box)
 
                    If e.Node.Checked Then
                        'Checkbox markieren
                        e.Graphics.DrawLine _
                             (p, .X, .Y, .X + .Height, .Y + .Height)
                        e.Graphics.DrawLine _
                             (p, .X + .Height, .Y, .X, .Y + .Height)
                    End If
 
                    'Text ausgeben (incl. Expand/Collapse-Zeichen)
                    Dim cs As String
                    If e.Node.Nodes.Count = 0 Then
                        cs = ""
                    Else
                        'Unterknoten: kollabiert oder expandiert?
                        If e.Node.IsExpanded Then cs = "(-) " Else cs = "(+) "
                    End If
                    e.Graphics.DrawString _
                        (cs & e.Node.Text, f, brfore, .X + .Height + 4, .Y)
 
                    'ggf. Verbindungslinien zu übergeordneten Knoten
                    Dim n As TreeNode = e.Node
                    Dim vertical As Boolean = True
                    While n.Parent IsNot Nothing
 
                        Dim start As Integer = _
                            n.Parent.Bounds.X + .Height \ 2
 
                        If vertical Then
                            e.Graphics.DrawLine _
                                (p, New Point(start, .Y + .Height \ 2), _
                                 New Point(.X - 4, .Y + .Height \ 2))
                            vertical = False
                        End If
 
                        e.Graphics.DrawLine(p, _
                           New Point(start, .Y + .Height), _
                           New Point(start, _
                           n.Parent.Bounds.Y + n.Parent.Bounds.Height))
 
                        n = n.Parent
                    End While
                End With
            End Using
        End With
    End Sub
 
 
     ''' <summary>Modus, in dem das Control gezeichnet wird (OwnerDrawAll)</summary>
    Public Shadows Property Drawmode() As TreeViewDrawMode
        Set(value As TreeViewDrawMode)
            '
        End Set
        Get
            Return MyBase.DrawMode
        End Get
    End Property
 
    ''' <summary>zu jedem Knoten wird ein Kontrolkästchen angezeigt</summary>
    Public Shadows Property Checkboxes() As Boolean
        Set(value As Boolean)
            '
        End Set
        Get
            Return MyBase.CheckBoxes
        End Get
    End Property
 
End Class
Klasse in das Projekt aufnehmen und Projekt übersetzen.
Danach findet sich in der Toolbox, Abschnitt <Projektname>,
ein neues Steuerelement.

Zu benutzen wie von Treeview gewohnt -
Scrollable-Eigenschaft auf false setzen, ggf. Scrollen
durch ein Scroll-Control durchführen,
per "Invalidate" das Neuzeichnen des TreeView verwalten.

Beitrag wurde zuletzt am 28.05.14 um 16:10:56 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: VB.net Treeview mit Checkboxes - Wie prüfe ich ob TopNode gecheckt wurde 
Autor: Jenpet
Datum: 28.05.14 16:06

Ah danke, jetzt hab ichs kapiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Immer noch .... 
Autor: Manfred X
Datum: 28.05.14 16:25

Diese Zeile
If e.Node.Bounds.Y = 0 And _
    Not Me.Nodes(0) Is e.Node Then Exit Sub 'Bug abfangen
ist zu ersetzen durch
  If e.Node.Bounds.Width = 0 Then Exit Sub 'Bug abfangen
So klappt es dann auch wieder mit dem Scrollen des Treeview.

Beitrag wurde zuletzt am 28.05.14 um 16:29:05 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel