Hi Leute,
mittlerweile bin ich echt am verzweifeln.
Es geht um folgendes: Ein Threeview hat normalerweise einen State, entweder checked oder unchecked.
Der Einfachheit halber beschränken wir uns in dem Beispiel mal auf ein Parent.Node, welches Child-Nodes hat.
Sind nun alle Child-Nodes auf checked, wird auch parent auf checked und vice versa. Das Gleiche gilt für unchecked.
Es gibt allerdings noch einen anderen Status, den Parent annehmen soll: Intermediate. Dieser Status wird erreicht, wenn mindestens ein Child-Node checked und nicht alle Child-Nodes checked sind.
Das Problem ist, dass sich das Icon für die Checkbox ändern soll wie etwa hier zu sehen:
Es gibt zwar einige Sample Code wie etwa von CodeGuru, CodeSamples etc., aber diese will ich meiden, da ich kene fremden Quellen implementieren will und ich alles schon selbst geschrieben habe, mir nur noch der letzte Teil fehlt.
Nach ewig langer Suche bin ich im Internet auf diesen Code gestoßen: activevb.de/cgi-bin/tippupload/show/361/ThreeStateTreeview
Allerdings weiß ich nicht, wie ich diesen Code implementieren soll bzw. mit meinem Treeview verknüpfen soll. Wie setze ich da ein Node nun auf intermediate?
Abwägig von diesem Code von der Internetseite habe ich versucht, mit CheckState.Intermediate oder Checked = Nothing zu arbeiten, leider alles erfolgslos.
Mein derzeitiger Code sieht so aus:
Zudem noch ein kleines Problemchen: Wenn ich einen Ordner angebe, in dem mehrere Ordner sind, wie zeige ich nur einen bestimmten Ordner im TreeView an? ich will also nicht alle gefundenen Ordner anzeigen, sondern nur einen. Habe es schon mit "if equal" versucht, nachdem ich den Name des Ordners vom Pfad extrahiert habe, klappt leider nicht ganz.
Ich wäre überaus glücklich, wenn mir jemand helfen kann
Grüße
mittlerweile bin ich echt am verzweifeln.
Es geht um folgendes: Ein Threeview hat normalerweise einen State, entweder checked oder unchecked.
Der Einfachheit halber beschränken wir uns in dem Beispiel mal auf ein Parent.Node, welches Child-Nodes hat.
Sind nun alle Child-Nodes auf checked, wird auch parent auf checked und vice versa. Das Gleiche gilt für unchecked.
Es gibt allerdings noch einen anderen Status, den Parent annehmen soll: Intermediate. Dieser Status wird erreicht, wenn mindestens ein Child-Node checked und nicht alle Child-Nodes checked sind.
Das Problem ist, dass sich das Icon für die Checkbox ändern soll wie etwa hier zu sehen:
Es gibt zwar einige Sample Code wie etwa von CodeGuru, CodeSamples etc., aber diese will ich meiden, da ich kene fremden Quellen implementieren will und ich alles schon selbst geschrieben habe, mir nur noch der letzte Teil fehlt.
Nach ewig langer Suche bin ich im Internet auf diesen Code gestoßen: activevb.de/cgi-bin/tippupload/show/361/ThreeStateTreeview
Allerdings weiß ich nicht, wie ich diesen Code implementieren soll bzw. mit meinem Treeview verknüpfen soll. Wie setze ich da ein Node nun auf intermediate?
Abwägig von diesem Code von der Internetseite habe ich versucht, mit CheckState.Intermediate oder Checked = Nothing zu arbeiten, leider alles erfolgslos.
Mein derzeitiger Code sieht so aus:
Quellcode
- Imports System.IO
- Imports CASHelper
- Imports System.Windows.Forms
- Imports System.Drawing
- Imports System.ComponentModel
- ''' <summary>
- ''' This class provides a TreeView to exclude packages
- ''' </summary>
- ''' <remarks></remarks>
- Public Class cExcludePackages
- Private sTopFolder As String
- Public Sub New(ByRef path As String) 'Parameter path from the folder. It's the parent
- InitializeComponent()
- sTopFolder = path
- GetDir(sTopFolder)
- End Sub
- ''' <summary>
- ''' Change states: if a parent node is checked, all subnodes are checked too. If parent is unchecked, all subnodes are unchecked too.
- ''' </summary>
- ''' <remarks></remarks>
- Private Sub TreeView1_AfterCheck(ByVal sender As Object, ByVal e As TreeViewEventArgs) Handles TreeView1.AfterCheck
- RemoveHandler TreeView1.AfterCheck, AddressOf TreeView1_AfterCheck
- Call CheckAllChildNodes(e.Node)
- If e.Node.Checked Then
- If e.Node.Parent Is Nothing = False Then
- Dim allChecked As Boolean = True
- Call IsEveryChildChecked(e.Node.Parent, allChecked)
- 'If every child is checked, check the parent too!
- If allChecked Then
- e.Node.Parent.Checked = True
- Call ShouldParentsBeChecked(e.Node.Parent)
- End If
- End If
- Else
- 'And vice versa
- Dim parentNode As TreeNode = e.Node.Parent
- While parentNode Is Nothing = False
- parentNode.Checked = False
- parentNode = parentNode.Parent
- End While
- End If
- AddHandler TreeView1.AfterCheck, AddressOf TreeView1_AfterCheck
- End Sub
- Private Sub CheckAllChildNodes(ByVal parentNode As TreeNode)
- 'When you start the application, al nodes should already be checked
- For Each childNode As TreeNode In parentNode.Nodes
- childNode.Checked = parentNode.Checked
- CheckAllChildNodes(childNode)
- Next
- End Sub
- Private Sub IsEveryChildChecked(ByVal parentNode As TreeNode, ByRef checkValue As Boolean)
- 'Recursive call: are all children checked?
- For Each node As TreeNode In parentNode.Nodes
- Call IsEveryChildChecked(node, checkValue)
- If Not node.Checked Then
- checkValue = False
- End If
- Next
- End Sub
- Private Sub ShouldParentsBeChecked(ByVal startNode As TreeNode)
- 'Determine if parents node should be checked or not
- If startNode.Parent Is Nothing = False Then
- Dim allChecked As Boolean = True
- Call IsEveryChildChecked(startNode.Parent, allChecked)
- If allChecked Then
- startNode.Parent.Checked = True
- Call ShouldParentsBeChecked(startNode.Parent)
- Else
- 'Actually this should be the intermediate status, but it doesn't work
- For Each child As TreeNode In startNode.Nodes
- If child.Nodes.Count > 0 And Not allChecked Then
- startNode.Parent.Checked = Nothing
- Call ShouldParentsBeChecked(startNode.Parent)
- End If
- Next
- End If
- End If
- End Sub
- Private Sub bFinish_Click(sender As Object, e As EventArgs) Handles bFinish.Click
- Me.Close()
- End Sub
- Private Sub GetDir(ByVal dirPath As String)
- Dim drives() As String = IO.Directory.GetDirectories(dirPath)
- Dim rootDir As String = String.Empty
- 'Set the parent nodes
- For i As Integer = 0 To drives.Count - 1
- rootDir = drives(i)
- 'add the nodes
- TreeView1.Nodes.Add(Path.GetDirectoryName(rootDir))
- PopulateTreeView(rootDir, TreeView1.Nodes(i))
- Next
- End Sub
- Private Sub PopulateTreeView(ByVal dir As String, ByVal parentNode As TreeNode)
- Dim folder As String = String.Empty
- Try
- 'Add the files to treeview
- Dim files() As String = IO.Directory.GetFiles(dir)
- If files.Length <> 0 Then
- Dim fileNode As TreeNode = Nothing
- For Each file As String In files
- fileNode = parentNode.Nodes.Add(IO.Path.GetFileNameWithoutExtension(file))
- fileNode.Checked = True
- fileNode.Tag = file
- Next
- End If
- 'Add folders to treeview
- Dim folders() As String = IO.Directory.GetDirectories(dir)
- If folders.Length <> 0 Then
- Dim folderNode As TreeNode = Nothing
- Dim folderName As String = String.Empty
- For Each folder In folders
- folderName = IO.Path.GetFileName(folder)
- folderNode = parentNode.Nodes.Add(folderName)
- folderNode.Checked = True
- folderNode.Tag = folder
- PopulateTreeView(folder, folderNode)
- Next
- End If
- 'If something went wrong...
- Catch ex As UnauthorizedAccessException
- parentNode.Nodes.Add("Access Denied")
- End Try
- End Sub
- End Class
Zudem noch ein kleines Problemchen: Wenn ich einen Ordner angebe, in dem mehrere Ordner sind, wie zeige ich nur einen bestimmten Ordner im TreeView an? ich will also nicht alle gefundenen Ordner anzeigen, sondern nur einen. Habe es schon mit "if equal" versucht, nachdem ich den Name des Ordners vom Pfad extrahiert habe, klappt leider nicht ganz.
Ich wäre überaus glücklich, wenn mir jemand helfen kann
Grüße