WPF 强制 TextBlock 呈现文本 属性

WPF force TextBlock to render the Text property

我有一个 WPF 应用程序,它会 运行 一堆可执行文件(通过进程)单击按钮。在表单中,有一个 TextBlock,我想用每个可执行文件的说明填充它。问题是,在流程完成之前,TextBlock 不会更新。我检查了调试器中的 TextBlock.Text 值,它有正确的文本,但没有显示。有没有办法强制 WPF TextBlock 显示其当前文本 属性?

这是我的代码:

MainWindow.xaml

<Grid>
        <TextBlock x:Name="InstructionsTextBlock" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding Instructions.Instructions, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Height="200" Width="287" Background="#FFB0BBAD"/>
        <Button Margin="52,223,525,149" x:Name="UpdateTextBlockAndRunExe" Content="Update TextBlock and run .exe" Click="UpdateTextBlockAndRunExe_Click"></Button>
</Grid>

MainWindow.xaml.cs

public partial class MainWindow: Window {
  MainViewModel _main = new MainViewModel();

  public MainWindow() {
    InitializeComponent();
    DataContext = _main;

    _main.SetInstructions("Initial Instructions");
  }

  private void UpdateTextBlockAndRunExe_Click(object sender, RoutedEventArgs e) {
    _main.SetInstructions("Before Exe - I want this to show up");

    string executablePath = Path.Combine(Utils.getResourcesDirectory(), "uniws", "uniws.exe");
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = false;
    startInfo.FileName = executablePath;
    startInfo.WindowStyle = ProcessWindowStyle.Normal;

    using(Process exeProcess = Process.Start(startInfo)) {
      exeProcess.WaitForExit();
    }

    _main.SetInstructions("After Exe - I want to end on this");
  }
}

MainViewModel.cs

public class MainViewModel {
  public InstructionsViewModel Instructions {
    get;
    private set;
  }

  public MainViewModel() {
    Instructions = new InstructionsViewModel();
  }

  public void SetInstructions(string instructions) {
    Instructions.Instructions = instructions;
  }
}

InstructionsViewModel.cs

public class InstructionsViewModel: ObservableObject {
  private string _instructions;

  public string Instructions {
    get {
      if (string.IsNullOrEmpty(_instructions))
        return "No instructions";
      return _instructions;
    }
    set {
      _instructions = value;
      OnPropertyChanged("Instructions");
    }
  }
}

ObservableObject.cs

public class ObservableObject: INotifyPropertyChanged {
  public event PropertyChangedEventHandler PropertyChanged;

  protected void OnPropertyChanged(string name) {
    if (PropertyChanged != null) {
      PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
  }
}

进程执行期间:

调试模式 - 显示文本 属性 已设置:

简而言之,没有。更新需要在 GUI 线程上完成,但您通过调用 WaitForExit 来阻止它。

处理此问题的最佳方法是使用异步编程。将您的点击处理程序更改为异步,然后使用 the answer to this question.

中的 WaitForExitAsync 函数等待每个进程完成

您可以使用调度程序:

Dispatcher.Invoke(() => _main.SetInstructions("Before Exe - I want this to show up"), DispatcherPriority.Send);

但我会像 Mark 那样推荐 async。