2009-08-25 4 views
2

Ich habe eine WinForms-Anwendung, die auf einem Arbeiter-Thread Daten von einem Web-Dienst abruft, und ich brauche die Eingabe in meine Anwendung zu deaktivieren, bis die Daten geladen wird.Wie blockiere ich alle Tastatur- und Mauseingaben in meine WinForms App?

Derzeit erstelle ich eine halbtransparente Form und legen Sie es über meine Anwendung. Wenn der Datenaufruf abgeschlossen ist, schließe ich dieses Overlay-Formular. Dies funktioniert gut, akzeptieren Sie, dass es erhebliche Leistungsprobleme für Benutzer verursacht, die die Anwendung über Terminaldienste ausführen. Ich habe versucht, das Overlay vollständig transparent zu machen, aber das löst immer noch zwei Neuzeichnungen des gesamten Fensters aus, so dass dies überhaupt nicht geholfen hat.

Ich weiß, dass eine allgemeine Empfehlung für die Handhabung ist, alle Steuerelemente zu deaktivieren, aber das würde auch einen großen Teil des Bildschirms neu zeichnen, also suche ich nach einer anderen Möglichkeit, alle Benutzereingaben zu blockieren. Jede Hilfe wäre sehr willkommen!

UPDATE: Ich habe zu erwähnen, dass wir den modalen Dialog betrachtet haben. Momentan zeigen wir das Overlay, starten den Datenzugriffsthread und konstruieren das Formular. Wenn es keinen besseren Weg eingegeben zu blockieren (App.BlockInput() könnte schön sein), dann könnten wir die modalen Dialog Idee verwenden, aber wir müssten warten, bis die Form der Bau abgeschlossen war, und es ist nicht ein schönes, zentral Standort, um dies zu tun.

Antwort

4

Sie könnten ein kleines modales Formular (modalForm.ShowDialog(yourForm)) mit Fortschrittsbalken anzeigen, der über Ihrer App läuft. Dies wird nicht dazu führen, dass große Bereiche neu gezeichnet werden.

+0

Aargh, schlagen Sie mich, um es von wenigen Sekunden ... Ich bin damit einverstanden, das ist wahrscheinlich der beste Weg, dies zu lösen. Außerdem hat ein modaler Dialog den Vorteil, dass es den Benutzer nicht so sehr verwirren kann, wie es ein geschlossenes Formular tun würde. –

+0

Sorry, ich habe vergessen zu erwähnen, dass wir das berücksichtigt haben. Sie können mein Update für die Frage für weitere Informationen sehen. Dies ist die beste Option, passt aber nicht so gut in unsere bestehende Codebasis. –

+0

Daniel, oops. Gute alte Zeiten von WinForms. Silverlight alle asynchronen Modelle sind so schwer zu bewältigen. Jim, vielleicht könnten Sie uns einen Code zeigen. Ist das Erstellen eines Formulars so teuer, dass Sie es berücksichtigen? Es scheint ein "Bettgeruch" im Code zu sein. –

2

Eine Sache, die Sie für die Tastatureingabe könnten versuchen, ist die Einstellung der KeyPreview Eigenschaft des Formulars auf True. Dadurch werden alle Tastaturereignisse zuerst an das Formularobjekt und nicht an die einzelnen Steuerelemente übergeben. Erstellen Sie einen Ereignishandler für das KeyPress-Ereignis des Formulars, und Sie können die Handled-Eigenschaft von KeyPressEventArgs auf True setzen, um zu verhindern, dass der Schlüsselstrich an eines der Steuerelemente übergeben wird. Wenn Sie derzeit Daten aus dem Webdienst abrufen, legen Sie die Handled-Eigenschaft auf True fest, andernfalls setzen Sie sie auf False, und der Schlüsselstrich wird an die Steuerelemente übergeben.

Wenn jemand eine gute Idee, wie die Mauseingabe zu handhaben noch Sie werden eingestellt.

+0

Vielen Dank für diesen Vorschlag. Ich habe KeyPreview schon einmal benutzt, aber noch nicht einmal darüber nachgedacht. –

3

Wenn Ihre App während der Ausführung des Vorgangs blockiert ist, würde ich tun, was Microsoft häufig tut: Öffnen Sie ein modales Dialogfeld mit einer Art Throbber-Animation oder ProgressBar und einer Schaltfläche Abbrechen. Neu zeichnen ist eingeschränkt, da Sie nur die Größe des neuen Dialogfelds zeichnen und die Eingabe in den Rest Ihrer Anwendung blockiert wird, da das Dialogfeld modal ist. Außerdem sind Benutzer eher bereit zu warten, wenn Sie Statusupdates und/oder Animationen haben, weil es so aussieht, als ob der Computer "funktioniert".

Wenn es jedoch Vorgänge gibt, die Ihr Benutzer ausführen kann, während Ihre Web-Service-Anforderung ausgeführt wird, ist es besser, die Steuerelemente zugänglich zu lassen. Zumindest sollte es immer einen Weg geben, den Prozess zu unterbrechen/abzubrechen.

Update: Da Sie nun die Frage geändert: Wie lange dauert es, den modalen Dialog zu erstellen? Warum nicht einfach den Dialog leer aufbauen und dann seine Steuerelemente auffüllen? Wenn Sie nur ein kleines Dialogfeld mit einer einzigen Schaltfläche und einer einzigen ProgressBar haben, sollte der Aufruf von dialog.ShowDialog() schneller erfolgen, als Ihr Benutzer mit Ihrer Benutzeroberfläche interagieren kann. Ist das nicht der Fall?

0

Normalerweise würde ich eine LockUI() - und eine UnlockUI() - Funktion in meinem Formular erstellen, die Steuerelemente umschaltet und ein lokales Formularfeld umkehrt, das als Flag für einen lang andauernden Prozess fungiert. Dieser Ansatz funktioniert sehr gut, wenn Sie ein Befehlsmuster verwenden.

Wie bereits erwähnt, können Sie die Tastatureingabe mithilfe der KeyPreview-Eigenschaft des Formulars umschalten (wie von TLiebe vorgeschlagen).

Für die Mauseingabe können Sie die Mausaktivität deaktivieren, indem Sie die WinProc messages einhängen und mouse input messages abfangen. Dies ist im Grunde, was KeyPreview tut.

Verwandte Themen