2010-02-18 21 views
19

Ich habe Code, der um ein randloses Formular in winforms gezogen werden kann, die ich seit einigen Monaten verwende, was sehr gut funktioniert.Invalidate vs Update

Aber als ich zuerst den Code bekam, verwendeten sie this.Invalidate(); im MouseMove Ereignis des Formulars, und die Form flackerte ein wenig und war langsam, wenn sie herumgezogen wurde. Also, ich ersetzte Invalidate() durch Update() im MouseMove Ereignis, und zu meiner Überraschung kann das Formular jetzt sehr glatt gezogen werden und hat überhaupt kein Flackern.

Kann mir jemand erklären, warum Update den Code besser funktioniert als Invalidate, auch wenn Invalidate so klingt, als wäre es der richtige?

Thanks :)

P. S. Vielleicht würde es mehr helfen, wenn ich den Code hinzufügen würde ... Jetzt hinzufügen.

bearbeiten - Hier ist der Code:


private void titlebar_MouseDown(object sender, MouseEventArgs e) 
{ 
    this.IsMouseDown = true; 

    this.LastCursorPosition = new Point(e.X, e.Y); 

    if (this.BackColor == Color.White) 
    { 
     this.BackColor = Color.GhostWhite; 
     tbox.BackColor = Color.GhostWhite; 
     tbox.ForeColor = Color.Black; 
    } 
    else 
    { 
     this.BackColor = Color.FromArgb(20, 20, 20); 
     tbox.BackColor = Color.FromArgb(20, 20, 20); 
     tbox.ForeColor = Color.White; 
    } 
} 

private void titlebar_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (this.IsMouseDown == true) 
    { 
     //Move the form 
     this.Location = new Point(this.Left - (this.LastCursorPosition.X - e.X), this.Top - (this.LastCursorPosition.Y - e.Y)); 

     // Update works better than Invalidate();. 
     Update(); 
    } 
} 

private void titlebar_MouseUp(object sender, MouseEventArgs e) 
{ 
    this.IsMouseDown = false; 
    this.BackColor = fc; 
    tbox.BackColor = fc; 
} 

Antwort

12

Invalidate markiert das Fenster als um aufgefrischt werden (irgendwann). Update tut es dort und dann, wenn ich mich richtig erinnere

Hier ist ein link den Unterschied besser zu erklären, als ich in der Lage wäre, zu

+2

Danke ein Haufen Martin. :) –

31

Invalidate() einfach fügen eine Region mit dem Aktualisierungsbereich der Steuerung. Beim nächsten Empfang von WM_PAINT werden der Bereich, den Sie für ungültig erklärt haben, sowie alle anderen ungültigen Bereiche zum Zeichnen markiert. Wenn RedrawWindow() aufgerufen wird, wird normalerweise eine WM_PAINT-Nachricht in die Anwendungswarteschlange gestellt. Das System ist frei, das zu tun, was es will, normalerweise ein dringenderes Geschäft, und zu malen, wenn es möglich ist.

Wenn Sie Update() aufrufen, erhalten Sie GDI + 's UpdateWindow(), die eine Region für Neuanstrich nicht markieren, sondern schiebt ein WM_PAINT direkt an WNDPROC(), die Anwendung Warteschlange umgehen.

Wenn Sie eine sofortige Aktualisierung einer Kontrolle benötigen , verwenden Refresh(), die die Region entkräftet ruft dann sofort Update().

+0

Ich weiß, das ist ein alter Beitrag und vielleicht sollte dies als eine separate Frage veröffentlicht werden, aber ich bin nicht klar, wann Sie Update verwenden würden und wann Sie Refresh verwenden würden. Es scheint, als ob beide ein sofortiges Repaint erzwingen. Können Sie klären? Vielen Dank! –

+4

@AdamPlocher Aus den Methodenkommentaren wird ersichtlich, dass 'Invalidate()' den Bereich einfach so kennzeichnet, dass er bemalt werden muss, aber nicht unbedingt malt. 'Update()' zwingt alle derzeit ungültigen Regionen neu zu streichen, markiert aber nichts. Und 'Refresh()' schließt die beiden Operationen zusammen, wobei zuerst die Region des Steuerelements als ungültig markiert wird und dann sofort die Region aktualisiert wird (neu gestrichen). ** Bearbeiten: ** http://Stackoverflow.com/a/952964/1718702 – HodlDwon