Treeview horizontale Scrollbar - Scroll-Position setzen/korrigieren?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Dideldum.

    Treeview horizontale Scrollbar - Scroll-Position setzen/korrigieren?

    Hi Ihr,

    wenn ich meine Trv befüllen lasse und die befüllten Knoten.values sind breiter als das Treeview, wird der Inhalt des Treeview nach links weggescrollt.
    Wie bekomme ich aber nach dem Befüllen der Nodes den Regler der horizontalen Scrollbar wieder ganz nach links auf die "0"-Position, so dass die Knoten rechts abgeschnitten sind und die Lines und "+"-Zeichen alle sichtbar sind?
    Ich habe viel versucht - aber nichts klappt.
    Wobei das doch eine wohl alltägliche Problemstellung ist - oder sein sollte.
    Finde im Web nur einen Tip dazu.

    VB.NET-Quellcode

    1. <DllImport("user32.dll", SetLastError:=True)>
    2. Private Shared Function GetScrollInfo(hWnd As IntPtr, nBar As Integer, ByRef lpsi As SCROLLINFO) As Boolean
    3. End Function
    4. <StructLayout(LayoutKind.Sequential)>
    5. Private Structure SCROLLINFO
    6. Public cbSize As UInteger
    7. Public fMask As UInteger
    8. Public nMin As Integer
    9. Public nMax As Integer
    10. Public nPage As UInteger
    11. Public nPos As Integer
    12. Public nTrackPos As Integer
    13. End Structure
    14. Private Sub AdjustTreeViewScrolling(treeView As TreeView, horizontalOffset As Integer)
    15. Dim scrollInfo As New SCROLLINFO()
    16. scrollInfo.cbSize = CUInt(Marshal.SizeOf(scrollInfo))
    17. scrollInfo.fMask = &H4
    18. scrollInfo.nPos = horizontalOffset
    19. GetScrollInfo(treeView.Handle, SB_HORZ, scrollInfo)
    20. End Sub
    21. Private Const SB_HORZ As Integer = 0


    Aber der funzt nicht.

    Kann mir da jemand von Euch vielleicht unter die Flügel greifen?

    Beste Grüsse
    @Dideldum Was passiert, wenn Du auf einen der betreffenden Knoten den Fokus setzt: TreeView.SelectedNode?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich kann das Szenario schon nicht nachstellen.

    Dideldum schrieb:

    und die befüllten Knoten.values sind breiter als das Treeview, wird der Inhalt des Treeview nach links weggescrollt.
    Nach links willst Du es doch haben. Passt also. Oder meinst Du nach rechts?
    Egal, ob ich Nodes mit überlangem Namen hinzufüge oder soviele Unternodes, dass diese nicht mehr angezeigt werden, das TreeView verbleibt auf Linksposition.
    Daher sind wohl mehr Details zum Nachbau nötig. Zumindest für mich.
    Bilder
    • Treeview.png

      1,93 kB, 99×240, 30 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hi Ihr,

    Mille gracie für Eure Tips.

    Uh, sorry.
    Habe mein Problem falsch beschrieben.
    Dachte, der Offset im Horizontal-Scroll wird bereits beim Befüllen gesetzt.
    Dank Rods Anmerkung habe ich die automatische Selektion meines Proggis testhalber aufgehoben und dann blieb die H-Scrollpos nach dem Befüllen der TRV tatsächlich auch auf 0.
    Sobald aber ein Node selektiert wird, dessen Value breiter ist, als die TRV.width, scrollt meine TRV horizontal von der 0-Position weg, um das selektierte Value des Nodes mgl. vollständig anzuzeigen.

    Genau das will ich aber nicht.
    Beim Selektieren soll die Scroll-Button-Position brav auf 0 bleiben.
    Bzw. eigentlich immer, ausser der User verschiebt den Button manuell.
    Ich kann das Problem immer noch nicht nachstellen. Egal, ob ich die überlangen Knoten mit Maus oder Tastatur selektiere, das TV bleibt, wo es sein soll. Ich hab auch mal ShowLines auf False und FullRowSelect auf True gemacht. Das gleiche.
    Kannst Du mal bitte das Projekt ohne bin-, obj-, .vs- und .git-Ordner und gezippt über [+ Erweiterte Antwort] hochladen? Vielleicht finden wir so das Problem und eine Lösung.
    Bilder
    • TreeView.png

      914 Byte, 101×257, 25 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hi @VaporiZed

    danke Dir für Deine Hilfe!

    Ich bin nun stepByStep meine Routine durchgegangen.
    Der Übeltäter ist:
    trv_Folders.SelectedNode.EnsureVisible()
    Ich dachte, dass dieser Befehl nur dafür sorgt, dass der ausgewählte Knoten in der Vertikalen sichtbar ist, also das TRV so vertikal gescrollt wird, dass der Knoten im sichtbaren Bereich liegt.
    Wie hier beschrieben:
    learn.microsoft.com/de-de/dotn…k(DevLang-VB)%26rd%3Dtrue
    Aber anscheinend wird dabei auch die horizontale Pos so verändert, dass mgl. der gesamte Knoten.value im TRV angezeigt wird.
    Das ensureVisible brauche ich ja unbedingt, damit der gewählte Knoten auch wirklich im TRV sichtbar ist.

    Daher habe ich mich nun so beholfen:

    VB.NET-Quellcode

    1. <DllImport("user32.dll")>
    2. Private Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
    3. End Function
    4. Private Structure SCROLLINFO
    5. Public cbSize As UInteger
    6. Public fMask As UInteger
    7. Public nMin As Integer
    8. Public nMax As Integer
    9. Public nPage As UInteger
    10. Public nPos As Integer
    11. Public nTrackPos As Integer
    12. End Structure
    13. Private Sub AdjustTreeViewScrolling(treeView As System.Windows.Forms.TreeView, horizontalOffset As Integer)
    14. Dim scrollInfo As New SCROLLINFO() With {.cbSize = CUInt(Marshal.SizeOf(GetType(SCROLLINFO))), .fMask = &H4}
    15. scrollInfo.nPos = horizontalOffset
    16. SendMessage(treeView.Handle, WM_HSCROLL, CType(SB_THUMBPOSITION + (horizontalOffset << 16), IntPtr), IntPtr.Zero)
    17. End Sub


    Das setzt nach dem:

    VB.NET-Quellcode

    1. OrdnerPfad = currentNode.FullPath
    2. trvFoldersAktNode = currentNode
    3. trv_Folders.SelectedNode = currentNode
    4. trv_Folders.SelectedNode.EnsureVisible()
    5. AdjustTreeViewScrolling(trv_Folders, 0)


    die H-Scrollbar wieder auf 0

    Nicht schön...
    Denn da zappelt die Anzeige im TRV kurz nach rechts und dann wieder auf die 0-Pos.

    Gibt es hierfür vielleicht eine bessere Lösung?
    "Umrande" mal Deinen Code mit folgenden Paaren. Vielleicht wird es damit besser. Also 1. Command vor Deinem Code, 2. Command danach:
    • trv_Folders.BeginUpdate/trv_Folders.EndUpdate
    • trv_Folders.SuspendLayout/trv_Folders.ResumeLayout
    • trv_Folders.Visible = False/trv_Folders.Visible = True
    Ist zwar alles eher Workaround, aber vielleicht hilft Dir ja eines davon weiter.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo @VaporiZed
    danke Dir für Deine Tips.
    Das Umfasssen mit Suspendlayout vor Zeile 1 und resumeLayout nach Zeile 6 habe ich schon im Code drin - und trotzdem stolpert das TRV sichtbar und ruckelt.
    Werde heute Abend mal Deine beiden anderen Tips testen.
    Nur, ob es schöner wird, wenn beim Ausblenden und Anzeigen der TRV im Mainform das ganze TRV kurz verschwindet?
    Da hört sich das BeginUpdate besser an - schon deshalb, weil mir deses ganz unbekannt ist. :D