Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I found a solution to my problem, so I'll share it in case you're interested.</p> <p>After some refactoring, I renamed the service's method I used in the question and created a new one. It's interface looks like this:</p> <pre><code>public interface IDialogService { /// &lt;summary&gt; /// Displays the specified dialog. /// &lt;/summary&gt; /// &lt;remarks&gt;This method is non-blocking. If you need to access the return value of the dialog, you can either /// provide a callback method or subscribe to the &lt;see cref="T:System.IObservable{bool?}" /&gt; that is returned.&lt;/remarks&gt; /// &lt;param name="dialog"&gt;The dialog to display.&lt;/param&gt; /// &lt;param name="callback"&gt;The callback to be called when the dialog closes.&lt;/param&gt; /// &lt;returns&gt;An &lt;see cref="T:System.IObservable{bool?}" /&gt; that broadcasts the value returned by the dialog /// to any observers.&lt;/returns&gt; IObservable&lt;bool?&gt; Show(Dialog dialog, Action&lt;bool?&gt; callback = null); /// &lt;summary&gt; /// Displays the specified dialog. This method waits for the dialog to close before it returns. /// &lt;/summary&gt; /// &lt;remarks&gt;This method waits for the dialog to close before it returns. If you need to show a dialog and /// return immediately, use &lt;see cref="M:Show"/&gt;.&lt;/remarks&gt; /// &lt;param name="dialog"&gt;The dialog to display.&lt;/param&gt; /// &lt;returns&gt;The value returned by the dialog.&lt;/returns&gt; bool? ShowDialog(Dialog dialog); } </code></pre> <p>The part that solves my problem is the implementation of <code>ShowDialog</code>:</p> <pre><code>public bool? ShowDialog(Dialog dialog) { // This will hold the result returned by the dialog bool? result = null; // We show a dialog using the method that returns an IObservable var subject = this.Show(dialog); // but we have to wait for it to close on another thread, otherwise we'll block the UI // we do this by preparing a new DispatcherFrame that exits when we get a value // back from the dialog DispatcherFrame frame = new DispatcherFrame(); // So start observing on a new thread. The Start method will return immediately. new Thread((ThreadStart)(() =&gt; { // This line will block on the new thread until the subject sends an OnNext or an OnComplete result = subject.FirstOrDefault(); // once we get the result from the dialog, we can tell the frame to stop frame.Continue = false; })).Start(); // This gets executed immediately after Thread.Start // The Dispatcher will now wait for the frame to stop before continuing // but since we are not blocking the current frame, the UI is still responsive Dispatcher.PushFrame(frame); return result; } </code></pre> <p>I think the comments should be enough to understand the code, which I can now use as so:</p> <pre><code>public bool? ShowConfirmationDialogs(IEnumerable&lt;ItemType&gt; items) { bool canContinue = true; foreach (var item in items) { Dialog dialog = new Dialog(); dialog.Prepare(item); // Prepares a "dialog" specific to each item bool? result = Service.ShowDialog(dialog); canContinue = result.HasValue &amp;&amp; result.Value; if (!canContinue) break; } if (!canContinue) { // do something that changes current object's state } return canContinue; } </code></pre> <p>I'd love to hear any comments or alternatives other users may have.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload