2010-01-21 12 views
6

Ich versuche, einen Bestätigungsdialog mit Silverlight ChildWindow Objekt zu tun.Silverlight Dialog bestätigt Thema bei Pause

Im Idealfall würde ich gerne wie MessageBox.Show() arbeiten, wo die gesamte Anwendung anhält, bis eine Eingabe vom Benutzer erhalten wird.

Zum Beispiel:

for (int i = 0; i < 5; i++) 
{ 
    if (i==3 && MessageBox.Show("Exit early?", 
     "Iterator", MessageBoxButton.OKCancel) == MessageBoxResult.OK) 
    { 
     break; 
    } 
} 

Würde die Iteration bei 3 stoppen, wenn der Benutzer auf OK trifft ...

war aber wenn ich etwas entlang der Linien tun:

ChildWindow confirm = new ChildWindow(); 
confirm.Title = "Iterator"; 
confirm.HasCloseButton = false; 
Grid container = new Grid(); 

Button closeBtn = new Button(); 
closeBtn.Content = "Exit early"; 
closeBtn.Click += delegate { confirm.DialogResult = true; confirm.Close(); }; 
container.Children.Add(closeBtn); 

Button continueBtn = new Button(); 
continueBtn.Content = "Continue!"; 
continueBtn.Click += delegate { confirm.DialogResult = false; confirm.Close(); }; 
container.Children.Add(continueBtn); 

confirm.Content = container; 

for(int i=0;i<5;i++) { 
    if (i==3) { 
    confirm.Show(); 
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) { 
     break; 
    } 
    } 
} 

Dies würde eindeutig nicht funktionieren, da der Faden nicht angehalten ... confirm.DialogResult.HasResult falsch sein würde, und die Schleife würde vergangen 3.

01 weiter

Ich frage mich nur, wie ich das richtig machen könnte. Silverlight ist single-threaded, also kann ich den Thread nicht einfach in den Ruhezustand versetzen und ihn dann aufwecken, wenn ich fertig bin, also frage ich mich, ob es noch etwas gibt, das die Leute empfehlen könnten?

ich als habe die Logik umgekehrt - das heißt, die Aktionen vorbei ich auf das Ja/Nein-Veranstaltungen stattfinden soll, aber in meinem speziellen Fall wäre dies nicht ganz funktioniert.

Vielen Dank im Voraus!

Antwort

11

Ich glaube nicht, Sie in der Lage sein, Ihren Code in einer Nachrichtenschleife so, wie Sie mit WinForms ShowDialog können zu blockieren.

Sie können jedoch Iteratoren missbrauchen den gleichen Effekt zu erzielen:

interface IAction { void Execute(Action callback); } 

public static void ExecAction(IEnumerator<IAction> enumerator) { 
    if (enumerator.MoveNext()) 
     enumerator.Current.Execute(() => ExecAction(enumerator)); 
} 

class DialogAction : ChildWindow, IAction { 
    void IAction.Execute(Action callback) { 
     //Show the window, then call callback when it's closed 
    } 
} 

IEnumerator<IAction> YourMethod() { 
    ... 
    var confirm = new DialogAction(); 
    yield return confirm; 
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) 
     yield break; 
    ... 
} 

dieses System zu nutzen, würden Sie ExecAction(YourMethod()); schreiben. Beachten Sie, dass dies ein halbblockierender Aufruf wäre und dass ich dies überhaupt nicht getestet habe.

Die neuen Funktionen von C# 5 async funktionieren genauso (die ursprünglichen Versionen des async Compiler-Codes basierten stark auf der vorhandenen Iterator-Implementierung), aber mit einer besseren syntaktischen Unterstützung.

+1

Das ist ziemlich genial! Ich gebe das eine Chance und sehen, wie gut es funktioniert ... – AlishahNovin

+0

Es kann leicht angenommen werden, um den Enumerator in einem Hintergrund-Thread ausführen, so dass eine sehr einfache Multi-Threaded UI-Workflow. – SLaks

+0

+1. Kleiner Punkt: meinst du nicht 'YieldMethod' mit" Rendite bestätigen "? –

1

können Sie diese ruhige erreichen leicht mit RX Framework:

var continued = Observable.FromEvent<RoutedEventArgs>(continueBtn, "Click"); 

var iter = new Subject<int>(); 

var ask = iter.Where(i => i == 3).Do(_ => confirm.Show()); 

iter.Where(i => i != 3 && i < 10) 
    .Merge(ask.Zip(continued, (i, _) => i)) 
    .Do(i => Debug.WriteLine("Do something for iteration {0}", i)) 
    .Select(i => i + 1) 
    .Subscribe(iter); 

iter.OnNext(0); 

Die Lösung leicht für jede Regel Skalen bestimmen, wann ein Dialogfeld zu zeigen. Z.B. Angenommen, wir möchten die Iteration blockieren und alle drei Iterationen eine Benutzerbestätigung anfordern. Alles, was Sie tun müssen, ist Bedingung i == 3 mit i % 3 == 0 (und i != 3 mit i % 3 != 0) zu ersetzen.

0

Schauen Sie sich dieses Projekt http://silverlightmsgbox.codeplex.com/. Es stellt eine einfache, aber vorzeigbare Implementierung mehrerer nützlicher Meldungsfelder dar, d. H. Bestätigung, Fehler, Information, Benutzereingabe usw., und könnte für Sie hilfreich sein. Viel Glück.

+0

Das hat nichts mit der Frage zu tun - er fragt nach einem Sperrruf. – SLaks

Verwandte Themen