【问题标题】:Update UI Thread from code [duplicate]从代码更新 UI 线程 [重复]
【发布时间】:2016-09-07 20:38:19
【问题描述】:

我应该如何编辑存在于 C# 任务之外的 WPF 数据?我已经使用标准 WPF 模板定义了一个 UI。网格仅包含:

<TextBlock x:Name="myTextBox" Text="Original Text" />

在我的代码中:

using System.Threading.Tasks;
using System.Windows;

namespace UpdateGUI
{
  public partial class MainWindow : Window
  {
    private int myInt;

    public MainWindow()
    {
      InitializeComponent();

      myInt = 0;
      Task.Factory.StartNew(() =>
      {
        myInt++;
        myTextBox.Text = "New Text";
      });
    }
  }
}

这会引发以下异常:

调用线程无法访问此对象,因为另一个线程拥有它。

哪个线程拥有 myTextBox?为什么我在编辑 myInt 时看不到此错误?

【问题讨论】:

  • 只有 UI 线程应该更新 UI 元素。如果另一个线程需要更新 UI,它应该要求 UI 线程去做。一种方法是通过Dispatcher class
  • 或者你可以使用双向绑定机制。将文本框绑定到模型上的属性,然后您可以更新模型,模型会自动更新文本框。
  • 您的示例代码的问题在于它过于简单,没有任何理由需要启动另一个线程。如果您有更具体的需求来解释为什么生成线程,也许我们可以更具体地指导您。
  • 您需要使用异步等待或使用 Dispatcher 调用将 UI 更新调用回 UI 线程。这被标记为欺骗,这是真的。但链接到 WinForm 解决方案,该解决方案不会延续到 WPF。欺骗答案应链接到 WPF 解决方案。
  • @rmcshry WPF 中的数据绑定是自切片面包以来最好的东西。值得花时间学习使用它。

标签: c# wpf multithreading


【解决方案1】:

您尝试做的事情是不可能的。您的代码在独立于 UI 线程的自己的线程中运行。

您需要了解有关 WPF 的更多信息。我知道有 2 种解决方案可以实现这一点:

  1. 对模型属性使用双向绑定
  2. 实现调度程序

选项 1 是执行此操作的常用方法,因此请了解两种方式绑定。调度员对于您正在尝试做的事情来说太过分了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    相关资源
    最近更新 更多