tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
1
ZUGRIFFE
1174
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    sVx sVx ist offline Grünschnabel
    Registriert seit
    Dec 2009
    Beiträge
    2
    Hallo Forum,

    such nun schon eine halbe Ewigkeit eine Lösung meines Problems, vermutlich eine ganz triviale Sache, aber ich kann einfach keine Ursache ausmachen; zumal viele Beispiele im Internet genauso aufgebaut sind und bei mir aber das gleiche Problem verursachen.

    Ausgangslage: habe ein Control, daß ein Kästchin zeichnet (quasi ProgressBar) und dort hinein einen Text mittels DrawString Schreibt. (Und rechtsbündig noch einen Bruch der auch den Fortschrit angibt.)

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    Pulic Class myprogressbar
        Inherits Control
     
        ' // alle privaten Variablen stehen hier oben
     
        Public Sub New()
            MyBase.New()
            Me.BackColor = Drawing.SystemColors.Window
            ' // ....... und so weiter, rest der Standardeinstellungen
        End Sub
     
        ' // passende Eigenschaften (Property-s) der Klasse sind hier auch definiert
     
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            Dim g As Graphics = e.Graphics
            Dim v As String = Me.Value.ToString & IIf(Me.DrawMaxValue, "/" & Me.MaximumValue, "")
            Dim r As Rectangle = New Rectangle(Me.InnerBorder, Me.InnerBorder, (e.ClipRectangle.Width / Me.MaximumValue) * m_value - (Me.InnerBorder * 2), e.ClipRectangle.Height - (Me.InnerBorder * 2))
            Dim th As Int16 = g.MeasureString(v, Me.Font).Height / 2
            Dim tw As Int16 = g.MeasureString(v, Me.Font).Width
            Dim b As Rectangle = New Rectangle(0, 0, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1)
            ControlPaint.DrawVisualStyleBorder(g, b)
            g.FillRectangle(New SolidBrush(Me.FillColor), r)
            If Me.Text <> "" Then
                g.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), Me.InnerBorder + Me.Padding.Left, e.ClipRectangle.Height / 2 - th)
            End If
            If Me.DrawValue Then
                g.DrawString(v, Me.ValueFont, New SolidBrush(Me.ForeColor), e.ClipRectangle.Width - g.MeasureString(v, Me.ValueFont).Width - Me.InnerBorder - Me.Padding.Right, e.ClipRectangle.Height / 2 - g.MeasureString(v, Me.ValueFont).Height / 2)
            End If
        End Sub
     
        ' // nur zur Fehlersuche
        Private Sub s_klick(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.SizeChanged, MyBase.Click
            Me.Invalidate()
        End Sub
    End Class

    Problem: Wenn nun andere Fenster, aber auch schon alleine das Menü des eigenen Fensters, Bereiche meines Controls überdecken und diese Bereiche später wieder sichtbar werden, wird der entsprechende Bereich nicht neu gezeichnet. (Bilder 1 bis 3 zur Verdeutlichung: Bild 1: so wie es sein soll; Bild 2: Fenster verdeckt Controls; Bild 3: Fenster gibt Control wieder frei, jedoch wird das Control nicht neu gezeichnet.)

    Zur Fehlersuche hatte ich mir auf das Ereignis "Click" ein "Invalidate()" gelegt, und dabei Festgestellt, daß die Fläche die OnPaint mit PaintEventArgs wohl auch "falsch" sein muß. (s. Bild 4)

    Wäre super, wenn mir jemand weiter helfen könnte, damit, wie jedes andere "normale" Control auch, mein Control auch ordentlich gezeichnet wird, wenn nach einer Verdeckung wieder sichtbar wird.

    Gruß
    sVx
    Miniaturansicht angehängter Grafiken Miniaturansicht angehängter Grafiken Kein Re-Paint nach Verdeckung des (eigenen) Controls-repaint-missing-01.png   Kein Re-Paint nach Verdeckung des (eigenen) Controls-repaint-missing-02.png  

    Kein Re-Paint nach Verdeckung des (eigenen) Controls-repaint-missing-03.png   Kein Re-Paint nach Verdeckung des (eigenen) Controls-repaint-missing-04.png  

    Geändert von sVx (13.12.09 um 20:20 Uhr) Grund: Paar Ergänzungen; Tippfehler entfernt
     

  2. #2
    sVx sVx ist offline Grünschnabel
    Registriert seit
    Dec 2009
    Beiträge
    2
    Ich kanns ja kaum glauben, aber habe nach "nur" vier Stunden den Fehler gefunden, weshalb OnPaint() das Control garnicht oder fehlerhaft an den stellen neu zeichnet an denen es von einem anderen Objekt überdeckt gewesen ist.

    So hat es den Anschein, daß es OnPaint() nicht schnell genug e.ClipRectangle erhällt. So habe ich nun eine globale Variable r angelegt in der (nur) jedes mal, wenn sich die größe des Controls ändert, ich e.ClipRectangle lese und in r ablege. In OnPaint() ist dann die Größe des Controls sofort aus r erhältlich und kann sofort zu weiteren Berechnungen in OnPaint() verwendet werden. Seit dieser Änderung blieben jedenfalls zuvor vorhandenen Probleme aus.

    Neue OnPaint(), zur Fehlersuche noch mal komplett neu geschrieben:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            Dim rect As Rectangle = Nothing
            Dim border As Rectangle = Nothing
            Dim th As Integer = Nothing
            Dim hpos As Integer = Nothing
            Dim v As String = Nothing
            '--- Bereich säubern respektive mit hintergrundfarbe ausmalen
            e.Graphics.Clear(SystemColors.Window)
            '--- Ladebalken
            border = New Rectangle(0, 0, r.Width - 1, r.Height - 1)   ' // -1 here to get border on bottom and right side too!
            rect = New Rectangle(Me.InnerBorder, Me.InnerBorder, (Me.Value - Me.MinimumValue) / Me.MaximumValue * r.Width, Me.Height)
            e.Graphics.FillRectangle(New SolidBrush(SystemColors.Highlight), rect)
            ControlPaint.DrawVisualStyleBorder(e.Graphics, border)
            '--- Beschriftung
            v = Me.Value & IIf(Me.DrawMaxValue, "/" & Me.MaximumValue, "")
            ' XXX: could be unlcean, depending on the implementation of MeasureString() // for VS2005 it is okay
            th = e.Graphics.MeasureString("m", Me.Font).Height
            hpos = r.Height / 2 - th / 2
            If Me.Text <> "" Then
                e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), Me.Padding.Left + Me.InnerBorder, hpos)
            End If
            If Me.DrawValue Then
                e.Graphics.DrawString(v, Me.ValueFont, New SolidBrush(Me.ForeColor), r.Width - e.Graphics.MeasureString(v, Me.ValueFont).Width - Me.Padding.Right - Me.InnerBorder, hpos)
            End If
    End Sub

    r wird hier berechnet:
    Code :
    1
    2
    3
    4
    
    Private Sub s_sizechanged(ByVal sender As Object, ByVal e As EventArgs) Handles Me.SizeChanged
            r = Me.ClientRectangle
            Me.Invalidate()
    End Sub

    Gruß,
    sVx

    PS: Kann ich meinen Beitrag jetzt selbst positiv bewerten?
    Geändert von sVx (13.12.09 um 22:54 Uhr)
     

Ähnliche Themen

  1. Paint kennt kein jpg mehr?
    Von sth_Weird im Forum Sonstige Grafik-Programme
    Antworten: 0
    Letzter Beitrag: 31.07.08, 07:53
  2. Kein paint()-Aufruf mehr durch repaint() nach Hinzufügen eines Dialogs
    Von Captain Code im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 23.10.07, 14:32
  3. Antworten: 0
    Letzter Beitrag: 20.09.05, 16:54
  4. Rendern von eigenen Controls in der Entwurfsansicht
    Von chironex im Forum .NET Windows Forms
    Antworten: 1
    Letzter Beitrag: 17.08.05, 15:34
  5. Antworten: 1
    Letzter Beitrag: 08.10.04, 17:27