| 

.NET C# Java Javascript Exception

3
Ich habe einen Dialog, der wahlweise über Show() und ShowDialog() aufgerufen werden kann. Über den OK-Schalter muss er geschlossen werden. Dazu muss DialogResult gesetzt werden, wenn der Dialog über ShowDialog() angezeigt wurde. Anderenfalls muss ich das Fenster über Close() schließen.

Wenn ich nun aber in einem nicht Modalen Dialog DialogResult setze erhalte ich eine InvalidOperationException. Ich muss also den aktuellen Ausführungsstatus ermitteln können, habe dazu aber nichts gefunden.

Über den Reflector konnte ich ermitteln, das intern das private Feld _showingAsDialog gesetzt wird, aber es gibt keine entsprechende öffentliche Eigenschaft. Und auch der ComponentDispatcher (in dem die modalen Fenster auf einen Stapel gelegt werden), gibt mir keine Möglichkeit, den Stapel abzufragen.

Es ist aber auch reichlich albern, folgendes zu programmieren:

try
{
DialogResult = true;
}
catch( InvalidOperationException )
{
Close();
}


Gibt es eine simple Möglichkeit, den Ausführungsstatus des Fensters zu ermitteln?
10.05.2011
Andreas Ganzer 1,4k 1 8
3 Antworten
2
Vielleicht könntest du es mit diesem Trick lösen:
public static bool IsModal(this Window window)
{
return typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance |
BindingFlags.NonPublic).GetValue(window);
}


via http://stackoverflow.com/questions/368926/how-do-i-determine-if-a-wpf-window-is-modal
10.05.2011
Konstantin 3,7k 1 8
Der Link ist gut, aber ich würde die dort akzeptierte Lösung (ComponentDipatcher.IsThreadModal) dem Reflection-Zugriff auf ein nicht dokumentiertes privates Feld eindeutig vorziehen.
Matthias Hlawatsch 10.05.2011
Ok das ist natürlich die bessere Lösung, hab ehrlich gesagt nicht weiter runtergescrollt ;-)
Konstantin 11.05.2011
3
Danke für die Antworten.

Wie ich sehe, scheint es keine "saubere" Lösung zu geben. Auch die Tipps auf Stackoverflow helfen nur in bestimmten Situationen.

So hilft z.B. das Überschreiben (Shadows/new) nicht, wenn verschiedene Dialoge an eine zentrale Methode mit der Signatur "bool PrepareAndShow(Window)" übergeben werden, weil dann immer ShowDialog() der Basisklasse aufgerufen würde.

ComponentDispatcher.IsThreadModal geht auch nur bedingt, weil ein nicht-modaler Dialog auch von einem anderen modalen Dialog geöffnet werden kann. In diesem Fall liefert IsThreadModal true obwohl der aktuelle Dialog nicht modal ist.

Die Reflection funktioniert einwandfrei und in allen Fällen, aber wir wissen nicht, ob das in einer kommenden .NET-Version noch immer so ist.

Da das Verhalten mit der Ausnahme nicht einfach in einer kommenden Version geändert werden darf (Kompatibilität zu bestehenden Anwendungen), ist das wohl die einzige allgemeingültige Alternative, bis Microsoft mal etwas öffentliches zur Verfügung stellt.

Ebenfalls würde in allen Situationen die Lösung von Barados korrekt arbeiten, aber der Aufrufer des Dialogs muss sich dabei um viel zu viele Dinge kümmern, die leicht vergessen werden können. Daher ist dieses sehr fehlerträchtig und umständlich.

Da die Antwort von Konstantin in der aktuellen .NET-Verison am zuverlässigtsten arbeitet und im Vergleich zur Antwort von Barados die günstigere Variante ist, werde ich diese mal als richtig markieren.
11.05.2011
Andreas Ganzer 1,4k 1 8
0
Mir war so als sei DialogResult ein enum...
Sollte man das einfach auf nen bool setzen?
10.05.2011
Barados 288 1 7
WPF !!! ;-)
Andreas Ganzer 10.05.2011
1
ok. verplant...

ein eigenes event kreieren was dann auf den Ok/Cancel/blubb-button gelegt wird und dass beim aufrufen registrieren? am sinnvollsten in eine in der aufrufenden funktion befindlichen anonymen funktion...
ist halt umständlich
Barados 10.05.2011

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH