Wpf 文本框赢得';在方法完成之前不要更新

Wpf 文本框赢得';在方法完成之前不要更新,wpf,data-binding,textbox,Wpf,Data Binding,Textbox,我尝试使用文本框显示正在完成的任务。基本上就像控制台应用程序如何显示正在发生的事情一样 但是,文本框中的文本仅在窗口加载完成后更新,然后所有文本都将显示,而不是实时显示 xaml代码: <Window x:Class="timelineTesting.Windows.CreateNewProject" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schem

我尝试使用文本框显示正在完成的任务。基本上就像控制台应用程序如何显示正在发生的事情一样

但是,文本框中的文本仅在窗口加载完成后更新,然后所有文本都将显示,而不是实时显示

xaml代码:

<Window x:Class="timelineTesting.Windows.CreateNewProject"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="CreateNewProject" Height="300" Width="579" Loaded="Window_Loaded_1">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBox Text="{Binding Path=LogData, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
t.Wait()
是一个阻塞调用。这意味着您实际上没有执行多线程。您启动任务,然后等待它完成。您应该做的是等待任务完成。

使用一个ProgressChanged事件,它可以用并发状态更新您的文本框


请参阅文章:它提供了一个示例。

使用
wait

private async void Window_Loaded_1(object sender, RoutedEventArgs e)
{
  Task t = Task.Run(() => Directory.CreateDirectory(this.ProjectName));
  LogData += "Starting new project creation...." + Environment.NewLine;
  LogData += "Creating project directory '" + ProjectName + "'....";
  try
  {
    await t;
  }
  catch (Exception ex)
  {
    LogData += "Error:" + Environment.NewLine;
    LogData += ex.ToString();
  }

  LogData += "Done!" + Environment.NewLine;

  t = Task.Run(() => File.Copy(this.VideoFilePath, newVideoPath));
  LogData += "Copying video file to project directory....";
  try
  {
    await t;
  }
  catch (Exception ex)
  {
    LogData += "Error:" + Environment.NewLine;
    LogData += ex.ToString();
  }

  LogData += "Done!" + Environment.NewLine;

  // many more tasks
}

您的问题是
Wait
正在阻塞GUI线程。GUI在忙着等待您的任务时无法更新。@MattBurland,但我认为等待会阻止,直到任务完成,当任务完成时,GUI不应再被阻止。然后添加到LogData字符串应该会更新GUI,直到我们再次等待。为什么不这样呢?在等待结束之前,我不会尝试添加到字符串。UI需要能够处理绘制消息,以便您查看更改。实际上,您没有返回到
Wait
s之间的UI循环,因此UI无法重新绘制自身。
private async void Window_Loaded_1(object sender, RoutedEventArgs e)
{
  Task t = Task.Run(() => Directory.CreateDirectory(this.ProjectName));
  LogData += "Starting new project creation...." + Environment.NewLine;
  LogData += "Creating project directory '" + ProjectName + "'....";
  try
  {
    await t;
  }
  catch (Exception ex)
  {
    LogData += "Error:" + Environment.NewLine;
    LogData += ex.ToString();
  }

  LogData += "Done!" + Environment.NewLine;

  t = Task.Run(() => File.Copy(this.VideoFilePath, newVideoPath));
  LogData += "Copying video file to project directory....";
  try
  {
    await t;
  }
  catch (Exception ex)
  {
    LogData += "Error:" + Environment.NewLine;
    LogData += ex.ToString();
  }

  LogData += "Done!" + Environment.NewLine;

  // many more tasks
}