Listbox hat nur grauen Balken

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

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von VB2021Aug.

    Listbox hat nur grauen Balken

    Ich experimentiere mit verschiedenen Steuerelementen.
    Ich wollte mal schnell aus einem Word-Makro ein VSTO-Projekt erstellen, das stellt sich schwieriger heraus, als ich gedacht hatte.

    Ich möchte eine ListBox (oder was auch immer) mit sichtbaren und unsichtbaren Spalten. (2: ID + Anzeige)
    Wenn der Eingabefocus nicht in der Listbox steht, dann soll trotzdem der Blaue Balken sichtbar sein (es gibt da eine Eigenschaft, aber damit wird der Balken entweder unsichtbar oder blass grau und fast nicht zu sehen!)

    Mit einem DataGridView funktioniert es halbwegs, habe aber auch Probleme, z.B. liefert mir das DGV im SelectionChanged noch den alten Wert in CurrentRow, so dass mein Formular jeweils die vorhergehenden Daten in den Textfeldern zeigt, während das DGV nach dem SelectionChanged den neuen Wert zeigt.

    Alles sehr verwirrend - "für mal eben schnell"...

    Danke an alle, die mir evtl. helfen wollen!

    VB2021Aug schrieb:

    ... Wenn der Eingabefocus nicht in der Listbox steht, dann soll trotzdem der Blaue Balken sichtbar sein ...


    Erstelle ein custom ListView mit folgendem code:

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' Set to explorer look.
    3. ''' </summary>
    4. Protected Overrides Sub CreateHandle()
    5. MyBase.CreateHandle()
    6. If ExplorerLook Then
    7. NativeMethods.SetWindowTheme(Handle, "explorer", Nothing)
    8. End If
    9. End Sub

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Public Class NativeMethods
    3. <DllImport("uxtheme.dll", CharSet:=CharSet.Unicode)>
    4. Public Shared Function SetWindowTheme(hWnd As IntPtr, pszSubAppName As String, pszSubIdList As String) As Integer
    5. End Function
    6. End Class


    Das müßte deinem Wunsch gerecht werden.

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

    Hallo ihr Lieben,
    Danke für eure Mithilfe!

    Ja, ErfinderDesRades, ich meinte ListView.

    Ich habe mit dem DataGridView experimentiert und mit ordentlicher Datenbindung wäre das vermutlich auch die richtige Lösung, ohne Datenbindung verhält sich das Ding z.T. recht merkwürdig.

    Und "FormFollowsFunction",
    dein Vorschlag ist sicher ziemlich genial, wenn ich nur wüsste, was er bedeutet!

    Ein custom ListView? Ich hab da also eine Klasse meinListView angelegt und Inherits ListView angegeben. (Ist das der Ansatz, den du meintest?)
    Mit ExplorerLook und NativMethods weiß mein Compiler leider nichts anzufangen.
    Welchen Verweis oder Imports müsste ich da setzen? Die Schnellhilfe zuckt da leider auch mit den Schultern.

    Entschuldige meine Anfänger-Fragen!

    VB2021Aug schrieb:

    Mit ExplorerLook und NativMethods weiß mein Compiler leider nichts anzufangen.

    NativeMethods ist eine Klasse die du selbst anlegen musst, ExplorerLook ist eine Variable die du anlegen kannst. In der Statischen NativeMethods Klasse musst du dann die Funktion SetWindowTheme Implementieren. Damit gwinnst du aber auch nichts. Da sobald die Listview den Fokus verliert auch hier das Selektierte Item grau hinterlegt wird. Du könntest das mit OwnerDraw erledigen, dass bedueted aber das du das zeichnen der Items selbst erledigen musst.
    Vielen Dank!
    Das sieht mir für den Moment nach einer Menge Arbeit und Googeln aus und mein eigentliches Projekt bleibt dabei stecken.
    (obwohl es sicher recht interessant und lehrreich wäre, sich etwa mit OwnerDraw zu beschäftigen!)

    Für den Moment kann ich mir damit behelfen, dass ich den Hintergrund der ListView etwas dunkler darstelle, dann ist wenigstens der weiße (lichtgraue) Balken für den Anwender zu erkennen.

    (keine Ahnung, was der Programmierer der ListView für einen schlechten Tag hatte, als er unnötigerweise am Design gedreht hat :/ Vielleicht ist er Firefox-Programmierer, die drehen auch ständig am Design, obwohl sich das niemand gewünscht hatte :D )
    Ist das nicht bei allen Steuerelementen so?

    Beispiel für OwnerDrawing

    C#-Quellcode

    1. using System.Drawing;
    2. using System.Windows.Forms;
    3. namespace WindowsFormsApp1
    4. {
    5. class MyListView : ListView
    6. {
    7. public MyListView()
    8. {
    9. OwnerDraw = true;
    10. }
    11. protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e)
    12. {
    13. base.OnDrawColumnHeader(e);
    14. e.DrawDefault = true;
    15. }
    16. protected override void OnDrawItem(DrawListViewItemEventArgs e)
    17. {
    18. base.OnDrawItem(e);
    19. if (View == View.Details && e.Item.Selected)
    20. {
    21. e.Graphics.FillRectangle(Brushes.AliceBlue, e.Item.Bounds);
    22. e.DrawText();
    23. }
    24. else
    25. {
    26. e.DrawDefault = true;
    27. }
    28. }
    29. }
    30. }

    VB2021Aug schrieb:

    Mit ExplorerLook und NativMethods weiß mein Compiler leider nichts anzufangen.

    Ups ! :rolleyes:
    Habe die Klasse hinzugefühgt.
    Hallo und vielen Dank euch beiden!
    Im Moment habe ich mir wie erwähnt mit einem dunklen Hintergrund beholfen.
    Langsam komme ich auch mit meinem Projekt voran und dann werde ich beide Varianten ausprobieren.
    OwnerDraw scheint mir auf lange Sicht konsistenter zu sein (solange ich keine Fehler mit Font, Brush, Rectangel etc. mache)
    Auch die Theme-Variante ist ziemlich interessant, vielleicht lassen sich hiermit auch andere Theme-Probleme lösen (nicht alles, was Neu ist, muss mir auch gefallen)

    Also, seid ihr mir böse, wenn ich das Thema schließe?
    Hallo Fakiz,

    Danke für das OwnerDraw-Beispiel!
    Hast du evtl. noch eine Ergänzung, wie ich die Textfarbe ebenfalls ändern kann.
    Ich war zwar schon in der Microsoft-Hilfe und habe etliches gesucht, da musste ich aber über e.Graphics.DrawString alle möglichen Parameter zusammen basteln. (Font, Brush, Rectangel...)
    Geht es auch einfacher?
    Einfach die ForColor im Draw-Event zu ändern führt in eine Endlosschleife, was ja logisch ist, aber man versucht so manches :D .

    Also, wenn du Zeit hast? Vielen Dank!
    Ich antworte mir hier mal selbst - für alle Interessierten

    Textfarbe Weiß für ausgewählten Datensatz.
    Anstelle e.DrawText() verwende ich nun e.Graphics.DrawString(..) wie folgt.

    VB.NET-Quellcode

    1. Protected Overrides Sub OnDrawSubItem(e As DrawListViewSubItemEventArgs)
    2. MyBase.OnDrawSubItem(e)
    3. If View = View.Details AndAlso e.Item.Selected Then
    4. e.Graphics.FillRectangle(Drawing.Brushes.RoyalBlue, e.Item.Bounds)
    5. e.Graphics.DrawString(e.SubItem.Text, e.Item.Font, New Drawing.SolidBrush(Drawing.Color.White), e.Bounds.X, e.Bounds.Y)
    6. Else
    7. e.DrawDefault = True
    8. End If
    9. End Sub


    Danke allen Mitdenkern und viel Erfolg für eure Projekte!
    Die SolidBrush Klasse implementiert das Interface IDisposable. Du musst also, wenn du das so machst, die Dispose Methode des Brushes aufrufen wenn du ihn nicht mehr brauchst. Oder du packst ihn in ein Using. Besser wäre hier aber wenn du die Statische Brushes Klasse verwenden würdest.

    Also anstelle von New SolidBrush(...) schreibst du Brushes.White
    Vielen Dank!
    Ich schätze mal, an die Hinweis über nicht aufgeräumte Klassenvariablen hängt eine Menge (schmerzlicher?) Programmiererfahrung.

    Nein, das mit den NtiveMethods habe ich nicht ausprobiert, das ist eher was für "Stille Winterabende" um mal den Horizont zu erweitern. ;)