Windows应用商店应用中的异步自定义对话框

时间:2014-05-05 12:49:32

标签: c# windows-runtime modal-dialog windows-store-apps winrt-xaml

是否可以在带有自定义内容的Windows应用商店应用中创建模态(异步)对话框?

我知道您可以显示消息对话框,但只能显示一些文本和按钮。在我的应用程序中,我需要填充一个组合框,让用户选择其中一个项目,然后才能执行其余的代码。

我已经找到了非对称的对话框(附加了代码)。到目前为止,它运作良好。
但是,现在我需要再次向用户检查所选设备是否正常,并且使用组合框在对话框上方显示消息对话框。

是否有(简单)方法“等待”我的第一个Dialog的结果?


这里是我用于ComboBox对话框的自定义弹出窗口的代码:

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();
    }

主页中的呼叫:

// 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是一个用于调用MessageDialog的简单助手类)

解决方案

感谢Nate Diamond我知道我应该寻找什么,所以我找到了答案: https://stackoverflow.com/a/12861824/2660864
我改变了一点,令人惊讶的是它现在有用了!

UsbSelectorPopup:

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

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

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

电话:

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

2 个答案:

答案 0 :(得分:4)

XAML有一个你想要的弹出控件。

<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>

在您的代码中,您可以通过切换IsOpen属性来打开和关闭它。

有意义吗?

祝你好运。

答案 1 :(得分:1)

一种简单的方法是使用TaskCompletionSource。这让你做的是返回一个Task(可以是Task),它只在你调用TaskCompletionSource.SetResult(T result)时返回。这意味着您可以在完成处理后执行所有异步处理并设置结果(或设置取消/错误)。

一个简单的例子是:

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);
}