带有文本输入的ContentDialog导致“该应用程序调用了一个已编组为不同线程的接口”

时间:2019-04-06 00:25:01

标签: c# uwp task

我不熟悉UWP Apps中的任务。在我遇到问题的代码部分中,我正在执行任务。然后,我需要

  1. 使用文本框实例化一个新的ContentDialog。
  2. 等待用户输入一些文本,然后单击ContentDialog上的按钮。
  3. 将值从ContentDialog传递回MainForm。
  4. 继续运行原始任务。

在ContentDialog的构造函数中运行InitializeComponent方法时出现错误。

我遍历了Google和StackOverflow,并且看到了使用ContentDialogs的示例,但没有什么能真正解决我的问题。实际上,我在应用程序的另一个位置使用ContentDialog向用户显示文本,但是我不需要从用户那里获得价值。

这篇帖子Text input in message dialog? ContentDialog?可能是我发现的最好的例子,但我无法使它正常工作。

await Task.Run(() => Parallel.ForEach(SourceDestination, async s =>
{                    
...
    if (NeedsPassword)
    {
            AskForPassword(s.Source, s.Extension, s.Destination);
    }                                
            ...                    
}));

private void AskForPassword(string file, string Ext, string destination = "")
{
    InputTextDialogAsync(file);

    if (m_sPassword != "")
    {
                ...                
    }            
}

private async void InputTextDialogAsync(string sFileName)
{            
   var dialog1 = new PasswordDialog();
   var result = await dialog1.ShowAsync();
   if (result == ContentDialogResult.Primary)
   {
       var text = dialog1.Text;
   }

}

<ContentDialog
    x:Class="....PasswordDialog"
    x:Name="ContentDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:..."
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="Enter Password for File"
    PrimaryButtonText="Submit"
    SecondaryButtonText="Cancel"
    PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
    SecondaryButtonClick="ContentDialog_SecondaryButtonClick">

    <Grid>
        <TextBox Text="{Binding ElementName=ContentDialog, Path=Text, Mode=TwoWay}" />
    </Grid>
</ContentDialog>

public sealed partial class PasswordDialog : ContentDialog
    {
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
           "Text", typeof(string), typeof(PasswordDialog), new PropertyMetadata(default(string)));

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public PasswordDialog()
        {
            this.InitializeComponent();
        }

        private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
        {
        }

        private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
        {
        }
    }

打开PasswordDialog时,在InitializeComponent上获得了本文标题中提到的错误。我认为这是因为我要从工作线程转到UI线程,但是我不确定该怎么做。任何帮助将不胜感激。

编辑: 谢谢@Alexei。我确实早些时候看过那篇文章,但是一开始我没有看到如何获得所需的价值。但是现在我明白了。这是我的最终代码:

private async Task<string> InputTextDialogAsync(string sFileName)
        {
            var taskCompletionSource = new TaskCompletionSource<string>();

            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
             async () =>
             {
                 var dialog1 = new PasswordDialog();
                 var result = await dialog1.ShowAsync();
                 if (result == ContentDialogResult.Primary)
                 {
                     var text = dialog1.Text;
                     taskCompletionSource.SetResult(text);
                 }
             }
         );
            return await taskCompletionSource.Task;
        }

我的理解是TaskCompletionSource将保存该值。使用taskCompletionSource.SetResult(text);进行设置。命令。感谢您的帮助。

0 个答案:

没有答案