/// <summary> /// Adds the commands to the popup and creates the machting wait handles. /// </summary> private void AddCommandsToPopup() { // In case no commmand is set, add a continue command without an action. if (CommandList.Count == 0) { CommandList.Add(new UICommand("Continue")); } // Remove exiting buttons in case ShowAsync was called more than once. ControlStackPanel.Children.Clear(); // Create the command delegate used when a button is pressed DelegateCommand <ManualResetEvent> commandDelegate = new DelegateCommand <ManualResetEvent>(OnButtonPressed); // Iterate over the list of commands. foreach (IUICommand command in CommandList) { // Create a new wait handle for the command ManualResetEvent waitHandle = new ManualResetEvent(false); // Add it to the list. WaitHandleList.Add(waitHandle); // Create the button and attach the wait handle. Button button = new Button() { Command = commandDelegate, CommandParameter = waitHandle, Content = command.Label, Style = (Style)Application.Current.Resources["ButtonStyle"] }; // Add the button to the popup ControlStackPanel.Children.Add(button); } }
/// <summary> /// Begins an asynchronous operation showing a dialog. /// </summary> /// <returns>Nothing.</returns> public async Task <IUICommand> ShowAsync() { // Add all commands to the command bar and create the matching wait handles. AddCommandsToPopup(); // Keeps the index of the signaled wait handle. int signaledHandle = -1; // Find the control currently having the focus Control focusedControl = FocusManager.GetFocusedElement() as Control; // Start the thread to wait for user input. Task waitForUserInputTask = Task.Run(() => { // Wait for a handle to be signaled. signaledHandle = ManualResetEvent.WaitAny(WaitHandleList.ToArray()); }); // Open the message box with a popup. Popup popup = PopupHelper.CreateFullScreenWithChild(this); // Set the focus on the defined button if (FocusCommandIndex >= 0 && FocusCommandIndex < CommandList.Count) { ((Button)(ControlStackPanel.Children[FocusCommandIndex])).Focus(FocusState.Programmatic); } // Wait for the wait thread to finish (one of the events to be signaled) await Task.WhenAny(new Task[] { waitForUserInputTask }); // Free all wait handles. while (WaitHandleList.Count > 0) { WaitHandleList[0].Dispose(); WaitHandleList.RemoveAt(0); } try { // Invoke the event handler of the selected command in case it is defined. if (CommandList[signaledHandle].Invoked != null) { CommandList[signaledHandle].Invoked.Invoke(CommandList[signaledHandle]); } } catch (Exception) { // re-throw any exception caused by the event handler. throw; } finally { // Make sure the popup will be closed. popup.IsOpen = false; // Release the message box from the popup popup.Child = null; // Reset the focus if (focusedControl != null) { focusedControl.Focus(FocusState.Programmatic); } } // Return the selected command return(CommandList[signaledHandle]); }