ListBox ohne vertikale Scrollbar

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von RobinH.

    ListBox ohne vertikale Scrollbar

    Hallo,

    zu diesem Thema habe ich auch hier schon einige Einträge gefunden, aber irgendwie nichts was auch wirklich funtioniert.

    Ich habe ein UserForm, mit einem TableLayoutPanel (nur zur Info, denke aber nicht, dass das hier wichtig ist).
    Dort enthalten sind u. a. 1x CheckedListbox und 2 x Listbox.

    Ich würde jetzt gerne vertikalen Scrollbars bei den beiden Listboxen permanent und dauerhaft ausblenden, egal, wie viele Einträge vorhanden sind.

    Bevor da Einwände kommen, dass man nicht alle Elemente anwählen kann.... die drei Listboxen werden parallel gescrollt, da die Einträge zusammengehören.
    Somit reicht mir ein Scrollbar in der CheckedListBox zum Scrollen von allen 3 Listen.

    Der Grund fürs Ausblenden ist:
    die eine ListBox enthält z. B. eine Zahl max. 3-stellig - durch die Scrollbar muss ich die Breite aber ca. verdoppeln, daher mein Wunsch nach Ausblendung.

    Falls möglich, am liebsten über Form_Load.

    Hat hier jemand eine Idee?
    Viele Grüße
    Robin
    @RobinH Mal sehen, ob ich es richtig verstanden habe:
    Du hast 3 gekoppelte Datensätze, die Du gemeinsam scrollen willst und in einer CheckedListBox und zwei normalen ListBoxen anzeigen willst.
    Wie wäre es mit einem DataGridView mit einer DataGridViewCheckBoxColumn und drei DataGridViewTextBoxColumns?
    Das dürfte genau das tun, was Du willst, sofern ich Dich richtig verstanden habe.
    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!
    Hallo Rod,

    tja also ich bin leider kein Profi - ich kenne das DataGridView nicht - habe ich bisher nie gebraucht :D

    Ich lerne aber gerne dazu, aber habe mit diesen Steuerelement so meine Probleme: ?(
    -ich habe ein DataGridView zum Testen in ein UF eingefügt und auch die von dir erwähnten 4 Spalten eingefügt (habe allerdings vorne vor der ersten links noch eine dazu bekommen, die ich aber nicht brauchen werde - nehm ich zumindest an), ka warum.....
    - mir ist es auch gelungen die Spaltenbreiten anzupassen, wenn man das UF vergrößert (2 haben feste Größen; 2 variabel 80/20) - wiedererkleinern ist mir da bisher noch nicht gelungen

    Da du das Steuerelement ja kennst, beantworte mir doch mal die folgenden Fragen, damit ich einfach entscheiden kann, ob sich die Zeit zum Lernen lohnt, weil ich es benutzen kann:
    1. ich brauche eine freie Sortierbarkeit (am besten mit der Maus die Zeilen verschieben)
    2. der Daten in der 1. Spalte darf nicht verändert werden (muss per Button eingetragen werden), die 2. und 3. Spalten dürften geändert werden (ginge aber auch per Button)
    3. ich möchte, dass sich das DataGridView an die Größe des UFs anpasst per Anchor (größer klappt, aber ich bekomme es irgendwie nicht wieder kleiner)

    Vielleicht hast du ja Zeit zu antworten. Alternativ würde ich auch eine Antwort auf meine ursprüngliche Frage nehmen? 8o
    Viele Grüße
    Robin

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RobinH“ ()

    RobinH schrieb:

    ob sich die Zeit zum Lernen lohnt
    In jedem Fall!
    Das DGV ist sehr komplex, du solltest zu jedem Deiner Probleme ein einzelnes neues Projekt und einen kommunizierenden Thread hier im Forum eröffnen.
    Ganz knapp und diagonal:
    Spaltenbreite => dgv.AutoSizeColumnsMode (Enum)
    Sortieren: So nicht, sorry.
    Daten per DataTable der Property dgv.DataSource zuweisen, geht dann in einem Einzeiler als XML zu speichern und zu laden;
    Sieh Dir mal dieses Beispiel an:
    Differenz in Prozent ausrechnen
    Such im Forum und der MSDN (Microsoft Docs) nach weiteren Beispielen und exerziere die durch.
    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!
    Hallo Rod,

    Sortieren: So nicht, sorry.


    Das ist aber bei mir sehr wichtig, dass ich die Reihenfolge selber völlig frei festlegen kann, aber ich kann dir zustimmen, das Teil ist echt interessant, aber für meinen derzeitigen Fall leider nicht das richtige, habe das zwar bisher veruscht, dass auf meine Bedürfnisse anzupassen und die Bücher, die ich zu VB habe, schreiben, teilweise, dass man darüber ein eigenes Buch schreiben könnte. Aber das hilft mir im Moment leider nicht weiter. Aber ich werde das im Auge behalten.

    Hast du eine Idee zu meiner ursprünglichen Frage bzgl. Ausblenden der Scrollbars?
    Viele Grüße
    Robin
    @RobinH Habs gefunden und probiert:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class Form1
    3. ''' <summary>
    4. ''' Aufzählung der Möglichkeiten
    5. ''' </summary>
    6. Private Enum Bar As Integer
    7. SB_HORZ = 0
    8. SB_VERT = 1
    9. SB_CTL = 2
    10. SB_BOTH = 3
    11. End Enum
    12. ''' <summary>
    13. ''' API-Deklaration
    14. ''' </summary>
    15. ''' <param name="hWnd"></param>
    16. ''' <param name="wBar"></param>
    17. ''' <param name="bShow"></param>
    18. ''' <returns></returns>
    19. <DllImport("user32.dll")>
    20. Private Shared Function ShowScrollBar(ByVal hWnd As IntPtr, ByVal wBar As Bar,
    21. <MarshalAs(UnmanagedType.Bool)> ByVal bShow As Boolean) As <MarshalAs(UnmanagedType.Bool)> Boolean
    22. End Function
    23. ''' <summary>
    24. ''' Schalten der Scrollbar
    25. ''' </summary>
    26. Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
    27. Form1.ShowScrollBar(Me.ListBox1.Handle, Bar.SB_VERT, Me.CheckBox1.Checked)
    28. End Sub
    29. ''' <summary>
    30. ''' definierte Ausgabgslage
    31. ''' </summary>
    32. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    33. Me.CheckBox1.Checked = True
    34. End Sub
    35. End Class
    Das geht auch für TextBoxen und Co.
    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!
    Hallo Rod,

    vielen Dank für deine Mühe (hat mich (siehe unten) auf eine Idee gebracht), ich habe mal versucht den Code auf mein UF anzupassen....
    mir ist zwar schleierhaft, warum ich da eine CheckBox brauche (will ja nur dauerhaft ausblenden und nicht hin und her wechseln), aber ich habe meine mal zweckentfremdet, da der Code dafür eh noch nicht geschrieben ist.

    Der Test ergibt folgendes:
    UF startet, CheckBox ist True, Scrollbar ist da - ich nehme den Haken raus - ist die Scrollbar weg - ok sie ist also schon mal zu entfernen :thumbup:

    ABER:
    wenn ich jetzt die Größe des UF ändere oder einfach nur die 1. Listbox (die mit Scrollbalken) scrolle, dann ist die ausgeblendete Scrollbar sofort wieder da - ich könnte diese dann durch ZWEI Klicks auf die CheckBox wieder ausblenden, aber das hält auch nur wieder bis zur nächsten Änderung.

    Ist auch ein DAUERHAFTES Ausblenden der vertikalen Scrollbar möglich, also vom Start des UF bis zum Schließen? Eigentlich soll die nämlich gar nicht da sein, egal wie viele Einträge in der ListBox sind.

    HEY momentchen - hatte grad eine Idee....... 8o

    Wenn ich bei deinem Spoilercode die Zeilen 30 bis 32 und 38 lösche und den Code von Zeile 31 in einen von den Timern schreibe und als letzten Parameter "False" einsetze, bekomme ich etwas, was zwar nicht 100 %ig das ist, was ich möchte, aber dem schon sehr nahe kommt....

    Die Scrollbars sind wie gewünscht weg!
    Sie Erscheinen zwar wieder bei UF-Größenänderungen oder beim Scrollen, aber wenn ich die Timerintervalle kürzer mache, z. B. 25, dann sind das nur kurze Augenblicke.
    Aber vielleicht hast du ja noch eine bessere Idee?
    Viele Grüße
    Robin

    RobinH schrieb:

    Aber vielleicht hast du ja noch eine bessere Idee?
    Zunächst einmal muss ich mich unendlich bei Dir entschuldigen, dass ich Dir nicht 110%igen Code für Dein Projekt geliefert habe, sondern nur eine Demonstration, wie das ganze prinzipiell funktioniert.
    Die CheckBox zeigt Dir, dass Du die ScrollBars zu- und wegschalten kannst.
    Wenn beim Resizen die ScrollBar erscheint, solltest Du sie beim Resizen wegnehmen, nicht in einem Timer.

    VB.NET-Quellcode

    1. Private Sub ListBox1_Resize(sender As Object, e As EventArgs) Handles ListBox1.Resize
    2. Form1.ShowScrollBar(Me.ListBox1.Handle, Bar.SB_VERT, False)
    3. End Sub
    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!
    Hallo Rod,

    sei bitte nicht sauer - ich bin dankbar für deine Hilfe und erwarte ja gar nicht einen 110%igen Code - ich lerne immer mehr je mehr ich mache, allerdings muss ich zugeben, dass ich mich mit XML-noch nicht beschäftigt hatte, aber ich habe den Code ja geändert bekommen. :S wenn auch nicht optimal

    Dein Code hat mich ja auf EINEN Weg gebracht - finde ich persönlich sogar besser, wenn man selber noch denken muss, dann lernt man etwas dazu.

    Allerdings kann ich dir nur bedingt zustimmen, was die Scrollbarwegnahme beim Resize entspricht. OK, das ginge bei einer Größenänderung, aber was, wenn ich die erste Listbox nur scrolle (dann schalten sich die beiden Scrollbars wieder ein)... eine ListBox.TopIndexChanged - Eigenschaft gibt es ja leider nicht
    im Moment seh ich zum Timer leider keine Alternative
    Obwohl ich den Timer ja eigentich abschalten könnte ?( , wenn die UF nicht sichtbar ist (weil das Programm soll eigentlich nur im Tray laufen) Die UF dient ja nur zum Einstellen des Programms.
    Viele Grüße
    Robin
    Ganz kurz: Was ist das Problem mit dem DGV? Die freie Sortierbarkeit ist ja auch mit (Checked)ListBoxes nicht so einfach umgesetzt. Hast Du dafür schon eine ListBox-Lösung? Wenn nicht, dann ist es natürlich etwas komisch, da beim DGV zu meckern. Letztenendes wird es dort ähnlich ablaufen. Daher wäre m.E. das DGV tatsächlich das, was Du brauchst. Du scheinst ja einen Datensatz bearbeiten bzw. sehen/selektieren zu wollen. Diesen in 3 Controls zu erfassen ist Pfeil-Rücken-Brust-Auge. Aber Moment. Vielleicht auch nicht. Wenn alle drei ListBoxen an dieselbe BindingSource gebunden sind, wird bei Selektion eines Datensatzes in einer ListBox der korrekte Eintrag in den anderen Boxen angezeigt …
    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,

    ich habe mich mit dem DGV ein wenig beschäftigt (ja ich hab gelesen, dass das DGV ein ziemlich endloses Thema ist) und optisch wäre das für mich wohl beinahe richtig. Ich habe das Vergrößern hinbekommen, aber die Verkleinerung des UF leider nicht, aber das ich nicht der Hauptgrund, warum das für mich nicht funktioniert - ich brauche eine eigene völlig wahllose Sortierung - :D - ein Sinn steckt da schon dahinter, aber den kann man nicht in Regeln fassen.

    Ich habe mir auf meinem UF eine CheckListBox und rechts daneben noch 2 Listboxen nebeneinander gelegt - Startbreiten auf Minimum (nach meinem Wunsch), wobei die letzte Listbox ihre Breite nicht ändert, da die Länge max. 3 Zeichen sein wird - also das funktioniert soweit auch.

    Wenn ich in der CheckedListBox einen Eintrag mit der Maus verschiebe (mit linker Taste drauf klicken -geht nur bei der CheckedListBox, verschieben, loslassen-fertig), verschieben sich die Einträge in den anderen beiden Listboxen entsprechend, auch wenn ich eine Listbox scrollen, scrollen die anderen entsprechend mit, markiere ich einen Eintrag egal in welcher Listbox, so wird bei den anderen beiden ebenfalls der entsprechende Eintrag markiert. Gelöst habe ich das mit MouseDown-MouseUP zum Verschieben und das Markieren mit einem Timer der den Index der angeklickten Listbox auf die anderen beiden überträgt. Muss noch mal experimentieren, ob der Timer auch läuft, wenn die UF ausgeblendet wird, weil das Prog im Tray ist, dann würd ich den vorher noch abschalten.

    Soweit funktioniert es schon so wie es soll - das einzige, was mich da ein wenig stört, sind die nicht erforderlichen Scrollbars bei Listbox 2 + 3. Die sind ohnehin eigentlich schmal, aber durch die Scrollbar verdoppelt sich die Breite fast. Daher mein Wunsch nach permenanter Ausblendung. Ein Timer ist hier sicher nicht die beste Lösung :rolleyes:

    Wenn ich das noch richtig im Kopf habe, dann habe ich versehentlich mal auf die Kopfzeile beim DGV geklickt und schon war die Liste sortiert - ein feine Sache, aber für mich hier leider nicht brauchbar.
    Viele Grüße
    Robin
    Dass der DGV-Inhalt bei ColumnHeaderClick sortiert wird, kannst Du bei den Column-Eigenschaften abschalten.
    Das mit den ScrollBars kannst Du so lösen, abgekupfert von stackoverflow. Das hier kommt in eine eigene Datei oder in Deine Form.VB:

    VB.NET-Quellcode

    1. Friend Class MyListBox : Inherits ListBox
    2. Private ShowScroll As Boolean
    3. Protected Overrides ReadOnly Property CreateParams() As CreateParams
    4. Get
    5. Dim cp = MyBase.CreateParams
    6. If Not ShowScroll Then cp.Style = cp.Style And Not &H200000
    7. Return cp
    8. End Get
    9. End Property
    10. Public Property ShowScrollbar() As Boolean
    11. Get
    12. Return ShowScroll
    13. End Get
    14. Set
    15. If ShowScroll = Value Then Return
    16. ShowScroll = Value
    17. If IsHandleCreated Then RecreateHandle()
    18. End Set
    19. End Property
    20. End Class
    Danach kompilierst Du Deine App, dann taucht im Designer in der ToolBox ganz oben MyListBox als Control auf. Das ziehst Du auf Dein Form und ersetzt so die normalen 2 ListBoxen. Diese MyListBox ist von Haus aus ohne vertikale ScrollBar (weil mit dem o.g. Code so voreingestellt). Timer werden dann nicht mehr benötigt.
    Das wilde Sortierten: Tja, wie gesagt: So wie Du es mit der CheckedLB machst, kannst Du es auch vom Prinzip her mit dem DGV machen.
    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.

    VaporiZed schrieb:

    Timer werden dann nicht mehr benötigt.
    Das wilde Sortierten: Tja, wie gesagt: So wie Du es mit der CheckedLB machst, kannst Du es auch vom Prinzip her mit dem DGV machen.


    Hallo VaporiZed,

    Dein Code ist spitze, er funktioniert genau so, wie er soll, allerdings so ganz ohne Timer geht es leider doch nicht.
    Ich brauche doch einen Timer zum Scrollen, sonst passen sich die beiden ListBoxen ohne die Scrollbar ja nicht an die erste an. ;)
    Und das wilde Sortieren ist mir bei dem DGV nicht so gut gelungen.

    Aber ich danke dir sehr für Deine Hilfe.

    Mit dem DGV werde ich mich auch mal beschäftigen, wenn ich mal Zeit dafür habe, aber im Moment scheint mir mein Weg (für einen Hobbybastler :D ) der einfachere zu sein. Daher wäre ich auch nie im Leben auf so eine Lösung, wie die deine gekommen, also nochmals besten Dank dafür.
    Viele Grüße
    Robin
    Naja, das mit dem Timer kannst Du Dir insofern sparen, dass Du entweder alles an eine BindingSource bindest oder im SelectedIndexChanged-EventHandler einer Box den SelectedIndex der anderen Boxen bearbeitest.
    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.

    VaporiZed schrieb:

    dass Du entweder alles an eine BindingSource bindest oder im SelectedIndexChanged-EventHandler einer Box den SelectedIndex der anderen Boxen bearbeitest.


    Sorry - hatte leider in den letzten Tagen zu wenig Zeit (ist bei mir ja nur Hobby).

    Also :D mit BindingSource kann ich leider nichts anfangen (da weiß ich leider nicht was oder wie ich das machen sollte - ich nehm auch mal an, dass das hier zu weit führen würde)

    und beim SelectedIndexChanged-Ereignis wird ja ein ausgewählter Index vorausgesetzt - das würde funktionieren, allerdings wird kein Item ausgewählt, wenn du nur auf dem Scrollbalken rumklickst und die Liste rauf oder runterscrollst - ein Timer hingegen kann das abfangen - da wüßte ich allerdings auch keine andere Lösung
    Viele Grüße
    Robin