Question

Is it possible to create a modal (asynchronous) dialog in a Windows Store App with custom content?

I know you can show a Message Dialog but only with some text and buttons. In my App I need to populate a Combo Box and let the user choose one of the items, before the rest of the code can be executed.

I already found something for a dialog which is not asynchronous (code is appended). It worked quite well until now.
However, now I need to check again with the user if the chosen device is okay and somehow the Message Dialog is shown above the Dialog with the Combo Box.

Is there a (simple) way to "wait" for the result of my first Dialog?


Here the code of the custom popup I am using for my ComboBox Dialog:

public sealed partial class UsbSelectorPopup : UserControl {

    public IList<DeviceInformation> deviceList { get; set; }
    public int ChosenEntry { get; set; }

    public UsbSelectorPopup(IList<DeviceInformation> deviceList) {
        this.InitializeComponent();
        this.deviceList = deviceList;
        PopulateComboBox();
    }

    private void PopulateComboBox() {
        ...
    }

    public void OpenPopup() {
        this.ParentPopup.IsOpen = true;
        this.gdChild.Visibility = Visibility.Visible;
    }

    public void ClosePopup() {
        this.ParentPopup.IsOpen = false;
        this.gdChild.Visibility = Visibility.Collapsed;
    }

    private void ChooseUsbBtn_Click(object sender, RoutedEventArgs e) {
        ChosenEntry = UsbComboBox.SelectedIndex;
        ClosePopup();
    }

    private void CloseUsbBtn_Click(object sender, RoutedEventArgs e) {
        ChosenEntry = 9999;
        ClosePopup();
    }

The Call in the MainPage:

// get all the USB Devices
var devices = ExamProvider.CustomStorageMedium.DeviceCollection;

// ask user which usb device to use
UsbSelectorPopup popup = new UsbSelectorPopup(devices);
popup.OpenPopup();

// get chosen device out of list
var chosenDevice = devices[popup.ChosenEntry];

// work with data on usb stick
 [...]

// ask user if he wants to continue with this device or choose another one
var result = await MessageBox.ShowAsync("You chose usb stick XYZ with file ABC on it. Do you want to continue?", MessageBoxButton.OkCancel);

(MessageBox is a simple Helper Class for calling MessageDialog)

Solution

Thanks to Nate Diamond I knew what it was I should look for and so I found this answer: https://stackoverflow.com/a/12861824/2660864
I changed it a bit and surprisingly it now works!

UsbSelectorPopup:

// Property
public TaskCompletionSource<int> UsbChosenTask { get; set; }

// in the constructor:
UsbChosenTask = new TaskCompletionSource<int>();

// In the Button Click Methods:
UsbChosenTask.TrySetResult(UsbComboBox.SelectedIndex);

The call:

UsbSelectorPopup popup = new UsbSelectorPopup(devices);
popup.OpenPopup();
var chosenEntry = await popup.UsbChosenTask.Task;
var chosenDevice = devices[popup.ChosenEntry];
Was it helpful?

Solution 2

One easy way to do this is with TaskCompletionSource. What this lets you do is return a Task (can be Task) which only returns when you call TaskCompletionSource.SetResult(T result). This means that you can do all of your asynchronous processes and set the result (or set cancel/error) when you are done processing.

A quick example would be:

private TaskCompletionSource<bool> taskCompletionSource;

private Task<bool> ShowAsync()
{
    //Do Show Stuff

    taskCompletionSource = new TaskCompletionSource<bool>();

    return taskCompletionSource.Task;
}

private void Close()
{
    //Do close stuff

    taskCompletionSource.SetResult(true);
}

OTHER TIPS

XAML has a popup control that is what you want.

<Popup x:Name="popup" IsOpen="True">
    <Grid Width="{Binding ActualWidth, ElementName=popup, Mode=OneWay}" 
            Height="{Binding ActualHeight, ElementName=popup, Mode=OneWay}">
        <!-- your content here -->
        <Rectangle Fill="Red" Opacity=".25" />
    </Grid>
</Popup>

In your code behind you can cause it to open and close by toggling the IsOpen property.

Make sense?

Best of luck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top