Hilfe mit dem DrawMode = OwnerDrawFixed

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

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

    Hilfe mit dem DrawMode = OwnerDrawFixed

    Guten Abend Community,

    Ich stehe vor einem Problem, als Element benutze ich eine ListBox.
    Diese ListBox versehne ich mit diesem Code:
    Dies ist die API auf die ich zugreife

    VB.NET-Quellcode

    1. Option Explicit
    2. ' benötigte API-Deklarationen
    3. Private Declare Function SendMessage Lib "user32" _
    4. Alias "SendMessageA" ( _
    5. ByVal hwnd As Integer, _
    6. ByVal wMsg As Integer, _
    7. ByVal wParam As Integer, _
    8. ByRef lParam As Integer) As Integer
    9. Private Const LB_SETTABSTOPS = &H192


    Das kommt in die ListBox rein:

    VB.NET-Quellcode

    1. Public Sub ListBox_SetTabStop(ByVal oList As ListBox, _
    2. ByVal ParamArray nTabs() As Integer)
    3. Dim nCount As Integer = nTabs.Length + 1
    4. ' TabStop-Werte zuweisen
    5. SendMessage(oList.Handle.ToInt32, LB_SETTABSTOPS, nCount, nTabs(0))
    6. End Sub


    Und so rufe ich diese auf:

    VB.NET-Quellcode

    1. ' Tabulator-Positionen festlegen
    2. ListBox_SetTabStop ListBox1, 70, 120
    3. ' Einträge sauber untereinander anzeigen
    4. With ListBox1.Items
    5. .Add(txb_1.Text & vbTab & txb_2.Text & vbTab & txb_3.Text)
    6. End With


    Das Funktioniert auch einwandfrei. Nun jetzt benutze ich für ein besseres Aussehen den DrawMode = OwnerDrawFixed
    Und schon habe ich das Problem das die ganze Funktion verbuggt ist.

    DrawMode = Normal das richtige ergebnis im bild002 und bei dem DrawMode = OwnerDrawixed sieht man auf dem bild001 das dieser verschoben ist.

    Man sieht mit dem DrawMode = OwnerDrawFixed ist die komplette Zeile sobald man die 1. Zeile verändert verbuggt, dies tritt beim Normalen DrawMode nicht auf.

    Kann man dieses Problem lösen?
    DrawMode muss die OwnerDrawFixed eigenschaft besitzen, da sonst das ganze Design unschön wird.

    Mit freundlichen Grüßen
    Die Sabine :saint:
    Bilder
    • 001.PNG

      2,04 kB, 342×59, 215 mal angesehen
    • 002.PNG

      1,67 kB, 342×56, 210 mal angesehen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Die_Sabine“ ()

    @Die_Sabine Willkommen im Forum. :thumbup:
    Du musst das ListBox.DrawItem-Event implementieren und dort alles zu Fuß machen, wie es sein soll.
    Gugst Du MSDN-Beispiel.
    =====
    Jou, es sieht allerdings so aus, als ob die Tabulatoren flöten gegangen seien, im Text selbst sind sie noch drin. :/
    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!
    danke :)

    schaue ich mir mal an.

    Aber die Tabulator sind ja da nur irgendwie nicht fixiert ;(

    Edit:

    VB.NET-Quellcode

    1. Private Sub ListBox2_DrawItem(sender As Object, e As DrawItemEventArgs) Handles ListBox2.DrawItem
    2. On Error Resume Next
    3. e.DrawBackground()
    4. If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
    5. 'Text color
    6. e.Graphics.FillRectangle(Brushes.SeaGreen, e.Bounds)
    7. End If
    8. Using b As New SolidBrush(e.ForeColor)
    9. e.Graphics.DrawString(ListBox2.GetItemText(ListBox2.Items(e.Index)), e.Font, b, e.Bounds)
    10. End Using
    11. e.DrawFocusRectangle()
    12. End Sub


    Hab ich auch nur wenn ich die DrawMode wieder zurückstelle dann sieht die ListBox wieder Normal aus :/
    Implementiere den Aufruf für Drawstring (siehe MSDN-Beispiel)

    und schreibe die 3 Strings jeweils einzeln an die gewüschte Position mit

    VB.NET-Quellcode

    1. e.Graphics.DrawString(part1, _
    2. e.Font, myBrush, rect1, StringFormat.GenericDefault)
    3. e.Graphics.DrawString(part2, _
    4. e.Font, myBrush, rect2, StringFormat.GenericDefault)
    5. e.Graphics.DrawString(part3, _
    6. e.Font, myBrush, rect3, StringFormat.GenericDefault)


    Die 3 Teile (part1-3) könntest du über Split auf vbTab ermitteln.
    Die Rect1-3 müssen natürlich innerhalb des Gesamt-Rect (e.Bounds) liegen.

    So kannst du die Tabulator-Position zu 100% selbst festlegen,
    bist nicht mehr an die Tabulator-Intepretation des Controls gebunden
    und selbst wenn einzlne Textteile länger oder kürzer sind, hast du immer noch
    fixe Positionen - Beispiel:

    DasErsteBeispielWortIstEinSehrLangesWort<vbTab>ZweitesWort1
    Wort2<vbTab>ZweitesWort2

    Mit dem einfachen Text-Tabulator würden ZweitesWort1 und ZweitesWort2 garantiert nicht mehr untereinander stehen ;)

    Duke schrieb:



    Die 3 Teile (part1-3) könntest du über Split auf vbTab ermitteln.
    Die Rect1-3 müssen natürlich innerhalb des Gesamt-Rect (e.Bounds) liegen.

    So kannst du die Tabulator-Position zu 100% selbst festlegen,
    bist nicht mehr an die Tabulator-Intepretation des Controls gebunden
    und selbst wenn einzlne Textteile länger oder kürzer sind, hast du immer noch
    fixe Positionen - Beispiel:

    DasErsteBeispielWortIstEinSehrLangesWort<vbTab>ZweitesWort1
    Wort2<vbTab>ZweitesWort2

    Mit dem einfachen Text-Tabulator würden ZweitesWort1 und ZweitesWort2 garantiert nicht mehr untereinander stehen ;)


    Danke :) aber kannst du mir bitte erklären wie ich das mache? Oder wenigstens einen Denkanstoß geben. :thumbsup:

    Duke schrieb:



    Die 3 Teile (part1-3) könntest du über Split auf vbTab ermitteln.
    Die Rect1-3 müssen natürlich innerhalb des Gesamt-Rect (e.Bounds) liegen.

    So kannst du die Tabulator-Position zu 100% selbst festlegen,
    bist nicht mehr an die Tabulator-Intepretation des Controls gebunden
    und selbst wenn einzlne Textteile länger oder kürzer sind, hast du immer noch
    fixe Positionen - Beispiel:




    Das Verstehe ich nicht.
    Na ganz grob so :

    VB.NET-Quellcode

    1. Private Sub LB_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs)
    2. ' Draw the background of the ListBox control for each item.
    3. e.DrawBackground()
    4. ' Define the default color of the brush as black.
    5. Dim myBrush As Brush = Brushes.Black
    6. Dim tabStops As New List(Of Int32) From {70,120}
    7. Dim parts = Me.Items(e.Index).ToString().Split(New Char() {vbTab}).ToList()
    8. Dim currentRect = e.Bounds
    9. currentRect.Width = tabStops(0)
    10. e.Graphics.DrawString(parts(0), e.Font, myBrush, currentRect, StringFormat.GenericDefault)
    11. currentRect.Offset(New Point(tabStops(0), 0))
    12. currentRect.Width = tabStops(1)
    13. e.Graphics.DrawString(parts(1), e.Font, myBrush, currentRect, StringFormat.GenericDefault)
    14. currentRect.Offset(New Point(tabStops(1), 0))
    15. currentRect.Width = e.Bounds.Width - tabStops(1)
    16. e.Graphics.DrawString(parts(2), e.Font, myBrush, currentRect, StringFormat.GenericDefault)
    17. e.DrawFocusRectangle()
    18. End Sub