【问题标题】:Asynchronous custom Dialog in Windows Store AppWindows 应用商店应用程序中的异步自定义对话框
【发布时间】:2014-05-07 16:31:35
【问题描述】:

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

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

我已经为非异步对话框找到了一些东西(附加了代码)。到现在为止它工作得很好。
但是,现在我需要再次与用户确认所选设备是否正常,并且消息对话框以某种方式显示在带有组合框的对话框上方。

有没有一种(简单的)方法可以“等待”我的第一个 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();
    }

主页中的调用:

// 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 的 Helper 类)

解决方案

感谢 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];

【问题讨论】:

  • 使用TaskCompletionSource&lt;T&gt; 是一种简单的方法。这让你做的是返回一个Task&lt;T&gt;(可以是Task),它只在你调用TaskCompletionSource&lt;T&gt;.SetResult(T result)时返回。这意味着您可以执行所有异步流程并在完成处理后设置结果(或设置取消/错误)。
  • 感谢您的评论。是否可以提供一个示例如何将任务与现有代码一起使用?我已经尝试了一些,但我对异步性没有太多经验,所以我不知道应该如何解决我的问题。
  • @NateDiamond 如果您愿意,可以添加答案,我会接受的

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


【解决方案1】:

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 属性来打开和关闭它。

有意义吗?

祝你好运。

【讨论】:

  • 嘿,谢谢你的回答。我的 xaml 中已经有弹出标签。主要问题是,在用户输入内容之前,我无法等待弹出窗口的结果和在弹出窗口显示后调用的 MessageDialog。 Nate Diamond 的回答解决了这个问题。
  • 总是有 AsTask().Wait()
【解决方案2】:

一种简单的方法是使用 TaskCompletionSource。这让您可以返回一个仅在您调用 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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 2013-03-03
    相关资源
    最近更新 更多