Auf Control zeichnen (innerhalb einer UserControl-Klasse (geerbt))

  • C#

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

    Auf Control zeichnen (innerhalb einer UserControl-Klasse (geerbt))

    Ich versuche seid längerem ein eigenes Control zu erstellen.
    Davor hatte ich ein Control geerbt, nehmen wir einfach beispielsweise das ListBox-Control.
    Darauf wollte ich zeichnen.
    Dafür habe ich die OnPaint-Methode überschrieben und versucht aufs Control zu zeichnen.
    Leider konnte ich nichts sehen.

    Dann habe ich die UserControl-Klasse geerbt und auch die OnPaint-Methode überschrieben und versucht, aufs Control zu zeichnen. (Natürlich hatte ich Invalidate() angewendet)
    Aber das selbe Problem.

    Dann habe ich ein Event hinzugefügt: DrawItem() vom ListView und habe es darüber versucht.
    Hat auch nicht geklappt.

    Mein Ziel ist es, auf ein Control zu zeichnen, innerhalb einer UserControl-Klasse.
    Hatte ich das über die Form gemacht, würde das gehen, aber ich möchte das direkt in UserControl machen.

    mfg

    //Edit: Mit einem Panel geht das, aber nicht mit einem ListView..
    //Edit 2: Wenn ich WinProc überschreibe, geht das.. mhmm..

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

    Und wie hast du das Überschrieben?
    Ich weiß nicht mehr genau wie das in VB.NET aussieht aber in C# gibt es beim Überschreiben automatisch sowas: base.OnPaint(e). Wenn du erst zeichnest und dann das aufrufst wird es natürlich wieder überzeichnet.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Ich habs inzwischen gelöst... leider musste ich einen Umweg nehmen.
    Ich habe die WinProc Methode überschrieben und eine virtual void erstellt, die das zeichnen übernimmt. So geht es anscheinend..
    Falls jemand einen anderen Weg kennt, bitte nennen.. :)
    Ist inzwischen entfernt.
    Ich überschrieb die Funktion und machte als ersten Schritt: base.OnPaint(e);
    Daraufhin zeichnete ich: e.Graphics.Drawblablabla
    Und dann machte ich ein Invaildidate().. aber nicht im Paint, sondern nach dem Button-Click (beispielsweise).. sodass gesagt wird, das es ungültig ist und neuzeichnet.

    Und ich habe ein erneutes Problem, es ist zwar kein direktes Problem, dennoch sehr nervig.
    Die bekomme ich das flackern beseitigt?
    this.DoubleBuffered = true ist schon gesetzt..

    P.S. Das ist eben nicht kompliziert, sondern einfach nur ein Umweg.
    Irgend etwas machst du gewaltig falsch/kompliziert. Zeig doch mal den Code. Ich kenn mich mit WinForms nicht wirklich aus aber dann könnte dir vll. auch mal jemand anders hier helfen.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Einige Controls haben eine Property namens OwnerDraw. Die musst du natrülich auf True setzen! Und dann gibt es bei Listenelementen oft Events wie DrawItem. Die bitte benutzen.

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !

    ListView.
    Wenn ich den OwnerDraw auf true geschalten habe, wird die Form an sich nicht mehr gezeichnet.
    Und wenn ich nach dem zeichnen es auf false stelle, wird mein Draw nicht mehr gezeichnet..

    ich denke ich habe vergessen die anderen mitzuzeichnen.. ich probiere es mal eben..

    //Edit: Es geht.. ich musste Background und Text natürlich auch zeichnen.
    Danke!
    ListView zeichnen ist ziemlich einfach.

    Das ist alles was man braucht: (Natürlich vorher OwnerDraw=True)

    VB.NET-Quellcode

    1. Private Sub ListView1_DrawColumnHeader(sender As Object, e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
    2. e.DrawDefault = True 'das system zeichnen lassen
    3. End Sub
    4. Private Sub ListView1_DrawSubItem(sender As Object, e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
    5. 'hier selbst zeichnen, wenn man items verändern will.
    6. End Sub


    Man sollte halt nur beachten, dass man DrawSubItem benutzt, statt DrawItem, weil das bisschen verbuggt ist. DrawSubItem wird auch für das Item selbst aufgerufen, da es ja das 0. SubItem ist.

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !

    Genau so habe ich es.. nur ich verwende die Items an sich.. keine SubItems.. aber das ist natürlich irrelevant :)
    trz. danke für deine Mühe.

    Wenn man darüber redet, fällt mir meist die Lösung selbst ein.. das ist für User wie ihr nervig.. :)

    Krischkros schrieb:

    nur ich verwende die Items an sich.. keine SubItems.. aber das ist natürlich irrelevant

    naja, nicht ganz irrelevant.
    Because of a bug in the underlying Win32 control, the DrawItem event occurs without accompanying DrawSubItem events once per row in the details view when the mouse pointer moves over the row, causing anything painted in a DrawSubItem event handler to be painted over by a custom background drawn in a DrawItem event handler. See the example in the OwnerDraw reference topic for a workaround that invalidates each row when the extra event occurs. An alternative workaround is to put all your custom drawing code in a DrawSubItem event handler and paint the background for the entire item (including subitems) only when the DrawListViewSubItemEventArgs.ColumnIndex value is 0.

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !