2 Stimmen

Deaktivieren des Neuzeichnens in WinForms-Anwendungen

Ich arbeite an einer C#.Net-Anwendung, die einen etwas lästigen Fehler hat. Das Hauptfenster hat eine Reihe von Registerkarten, von denen jede ein Gitter hat. Beim Wechsel von einer Registerkarte zu einem anderen, oder die Auswahl einer anderen Zeile in einem Raster, tut es einige Hintergrundverarbeitung, und während dieser das Menü flackert, wie es neu gezeichnet wird (Datei, Hilfe, etc. Menüpunkte sowie Fenstersymbol und Titel).

Ich habe zunächst versucht, das Neuzeichnen des Fensters beim Umschalten von Registerkarten/Zeilen zu deaktivieren (WM_SETREDRAW-Meldung). In einem Fall funktioniert es perfekt. Im anderen Fall löst es den unmittelbaren Fehler (Titel-/Menüflimmern), aber zwischen dem Deaktivieren des Neuzeichnens und dem erneuten Aktivieren ist das Fenster für Mausklicks "transparent" - es gibt ein kleines Fenster (<1 Sek.), in dem ich klicken kann, und es wird z. B. ein Symbol auf meinem Desktop hervorgehoben, als ob die Anwendung überhaupt nicht vorhanden wäre. Wenn ich etwas anderes im Hintergrund laufen habe (z. B. Firefox), erhält es tatsächlich den Fokus, wenn ich darauf klicke (und zeichnet einen Teil des Browsers, z. B. die Adressleiste).

Hier ist der von mir hinzugefügte Code.

m = new Message();
m.HWnd = System.Windows.Forms.Application.OpenForms[0].Handle; //top level
m.WParam = (IntPtr)0; //disable redraw
m.LParam = (IntPtr)0; //unused
m.Msg = 11; //wm_setredraw
WndProc(ref m);

<snip> - Die Anwendung ignoriert Klicks in diesem Abschnitt (in einem Fall)

m = new Message();
m.HWnd = System.Windows.Forms.Application.OpenForms[0].Handle; //top level
m.WParam = (IntPtr)1; //enable
m.LParam = (IntPtr)0; //unused
m.Msg = 11; //wm_setredraw
WndProc(ref m);

System.Windows.Forms.Application.OpenForms[0].Refresh();

Weiß jemand, ob a) es eine Möglichkeit gibt, das Problem der transparenten Anwendung hier zu beheben, oder b) ob ich es in erster Linie falsch mache und dies auf eine andere Weise behoben werden sollte?

4voto

Jeff Yates Punkte 59874

Es gibt Aufrufe von Klassen, die von Control zu diesem Zweck. Sie sind SuspendLayout y PerformLayout . Da sie sich auf Control y Form wird abgeleitet von Control , Ihr Form hat sie auch.

Diese Aufrufe reichen für die meisten Aktualisierungen aus, aber unter anderen Umständen reicht es aus, das Steuerelement mit Visible = false kann ausreichend sein. Um das Flackern während des Ausblendens und Wiedereinblendens des Steuerelements zu verhindern, zeichne ich das Steuerelement normalerweise in eine Bitmap, die ich in einer PictureBox während der Aktualisierung. Dies ist nützlich bei der Aktualisierung von Bäumen, Registersteuerelementen oder Listen (ebenso wie das Ausschalten der Sortierung während der Aktualisierung in diesem letzten Beispiel).

0voto

MusiGenesis Punkte 72729

Das Verhalten, das Sie beschreiben, ist nicht normal für eine .NET-Winforms-Anwendung. Die Tatsache, dass Sie WndProc und das Senden von Nachrichten in Ihrem Beispiel verwenden, deutet darauf hin, dass eine Menge anderer ungewöhnlicher Dinge mit diesem Formular vor sich gehen (ich vermute, dass mehr als ein Thread beteiligt ist). Eine andere Möglichkeit, die bei Oberflächen mit Registerkarten häufig vorkommt, ist, dass Ihr Formular einfach mit Steuerelementen überladen ist; manchmal kann dies zu einem seltsamen Verhalten führen.

Ich habe noch nie etwas gesehen oder gehört, das auch nur im Entferntesten dem entspricht, was Sie beschreiben.

0voto

Wolf5 Punkte 15450

Sie können versuchen, die Paint-Methode Ihres Steuerelements, das nicht gerendert werden soll, zu überschreiben und durch ein globales Bool zu steuern (= alles Malen ignorieren, solange ein Bool wahr ist). Wenn Ihr Steuerelement ein 3rd-Party-Steuerelement ist, subclass es und überschreiben Sie es dort.

Dann, wenn Sie zufrieden sind, setzen Sie das bool auf false und lassen Sie das Steuerelement wieder gezeichnet werden (möglicherweise müssen Sie ein Bild erzwingen, wenn Sie es wieder mit .Refresh? einschalten)

0voto

Avish Punkte 4186

Wenn es sich um ein benutzerdefiniertes Steuerelement handelt, können Sie einige der Kontrollstil Flaggen: Ich denke, DoubleBuffered oder AllPaintingInWmPaint könnten helfen. Sie können die Stilbits ändern mit Control.SetStyle (die geschützt ist, weshalb Sie dies in Ihrer eigenen benutzerdefinierten Steuerklasse tun müssen).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X