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
1 Answer 1
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;
}
TopMost
property of the dialog form is set to true. Now theShow()
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\$