6
\$\begingroup\$

I need a simple prompt window to ask the user to do something with an OK/Cancel return. But I also need all Windows to remain functional, so a xx.ShowDialog isn't appropriate.

This is my attempt. DialogWindow takes a Delegate in the constructor and calls it when OK or Cancel is clicked with a True/False parameter respectively. The Window is coded to take top Z priority.

It seems to work but I'm not very knowledgeable on await usage. Is there an easier way?

        bool result;
        ManualResetEvent manualReset = new ManualResetEvent(false);
        DialogWindow myDialog = new DialogWindow((dialogResult) =>
        {
            result = dialogResult;
            manualReset.Set();
        });
        myDialog.Show();
        await Task.Factory.StartNew(() =>
        {
            manualReset.WaitOne();
        });
        //Do something with result
\$\endgroup\$
1
  • \$\begingroup\$ You could do the same by making sure the TopMost property of the dialog form is set to true. Now the Show() method will place the dialog on top and any other forms can still take focus. Once a new dialog form is instantiated you can access any of its controls and properties that aren't private. \$\endgroup\$ – tinstaafl Oct 9 '14 at 20:36
4
\$\begingroup\$

Using ManualResetEvent this way means that you're blocking a thread unnecessarily while the dialog is shown. Instead, you should use TaskCompletionSource, which allows you to create a Task that completes when you want it to.

Encapsulated into a method, the code could look something like this:

public static Task<bool> ShowAsync()
{
    var tcs = new TaskCompletionSource<bool>();
    var dialog = new DialogWindow(tcs.SetResult);
    dialog.Show();
    return tcs.Task;
}
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.