【问题标题】:C# WPF - How to simply update UI from another class/threadC# WPF - 如何从另一个类/线程简单地更新 UI
【发布时间】:2015-11-12 20:08:26
【问题描述】:

我找不到针对此问题的简单解决方案。这就是我问的原因。

我有一个像这样的 WPF 窗口

<Window x:Class="WPF_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="640" Height="480">

    <Button Name="xaml_button" Content="A Text."/>
</Window>

还有一个 MainWindow

using System.Windows;
using System.Threading;

namespace WPF_Test
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            xaml_button.Content = "Text changed on start.";
        }
    }

    private void xaml_button_Click()
    {
        Threading.t1.Start();
        UIControl.ChangeButtonName("Updated from another CLASS.");
    }
}

按钮的Content 属性成功改变了自身。但我想做的是更改 another 线程中的属性。我尝试的是这样的:

class UIControl
{
    public static void ChangeButtonName(string text)
    {
        var window = new MainWindow();
        window.xaml_button.Content = text;
    }
}

显然不起作用,因为public MainWindow()Content 属性更改回原来的属性,并随之带来一些问题。

我也想在 多线程 时使用它。我的简单线程类如下所示:

class Threading
{
    public static Thread t1 = new Thread(t1_data);

    static void t1_data()
    {
        Thread.Sleep(2000);
        UIControl.ChangeButtonName("Updated from another THREAD.");
    }
}

【问题讨论】:

标签: c# wpf multithreading user-interface


【解决方案1】:

为此,我建议声明一个 static 变量来保存您喜欢的 UI 控件,在本例中为 Button。还要在开头添加using System.Windows.Controls;。所以你的代码应该是这样的:

using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace WPF_Test
{
    public partial class MainWindow : Window
    {
        public static Button xamlStaticButton;

        public MainWindow()
        {
            InitializeComponent();
            xamlStaticButton = xaml_button;
            xamlStaticButton.Content = "Text changed on start";
        }

        private void xaml_button_Click(object sender, RoutedEventArgs e)
        {
            Threading.t1.Start();
            UIControl.ChangeButtonName("Updated from another CLASS.");
        }
    }
}

我所做的几乎就是为按钮制作一个占位符,然后在开始时分配它。

class UIControl : MainWindow
{
    public static void ChangeButtonName(string text)
    {
        App.Current.Dispatcher.Invoke(delegate {
            xamlStaticButton.Content = text;
        });
    }
}

现在,为了方便起见,我将MainWindow继承UIControl 类。为了使这项工作与多线程一起工作,我添加了App.Current.Dispatcher.Invoke(delegate { /*your UI code you want to execute*/});。这将确保即使您在另一个线程上,您的 UI 也会更新。

【讨论】:

  • 好多了:使用 MVVM 并将按钮内容绑定到视图模型属性。
  • 我会支持@Clemens。查看 MVVM 轻量级工具包:mvvmlight.codeplex.com
猜你喜欢
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多