WPF:刷新其他线程中的控件

本文关键字:控件 线程 其他 刷新 WPF | 更新日期: 2023-09-27 17:50:20

我有一个简单的WPF应用程序,我使用线程。例如:在新的线程中,我得到DateTime,我想把它返回到主线程的文本框。我读到这样做,我必须使用ControlDispatcher。调用方法。但是有些地方不对……

namespace Bizantyjskie
{
    public static class ControlExtensions
    {
        public static void InvokeIfRequired(this Control control, Action action)
        {
            if (System.Threading.Thread.CurrentThread != control.Dispatcher.Thread)
                control.Dispatcher.Invoke(action);
            else
                action();
        }
        public static void InvokeIfRequired<T>(this Control control, Action<T> action, T parameter)
        {
            if (System.Threading.Thread.CurrentThread != control.Dispatcher.Thread)
                control.Dispatcher.Invoke(action, parameter);
            else
                action(parameter);
        }
    }
    class watki
    {
        public watki(MainWindow mw)
        {
            _mw = mw;
        }
        public MainWindow _mw;
        public void dzialaj()
        {
            Thread watek1 = new Thread(new ThreadStart(w1));
            watek1.Start();
        }
        private void w1()
        {
            string godz = DateTime.Now.TimeOfDay.ToString();
            ControlExtensions.InvokeIfRequired((value) => _mw.tb_w1.Text = value, godz);
        }
      }
     }

问题是

ControlExtensions.InvokeIfRequired((value) => _mw.tb_w1。Text = value,godz);

出现错误。

不能将lambda表达式转换为类型"System.Windows.Controls。控件',因为它不是委托类型

WPF:刷新其他线程中的控件

您将扩展方法作为静态方法调用,而忘记传递参数。改成这样:

_mw.InvokeIfRequired(value => _mw.tb_w1.Text = value, godz);

或者,如果您仍然希望将其作为静态方法调用:

ControlExtensions.InvokeIfRequired(_mw, 
    value => _mw.tb_w1.Text = value, godz);

试试这个

private void w1()
{
    string godz = DateTime.Now.TimeOfDay.ToString();
    ControlExtensions.InvokeIfRequired((value) => { _mw.tb_w1.Text = value; }, godz);
}

因为我认为你的"值"成员是传递给委托的参数,虽然我不能确定没有看InvokeIfRequired的签名-如果它是object,你不需要强制转换吗?

ControlExtensions.InvokeIfRequired((value) => { _mw.tb_w1.Text = (string)value; }, godz);

编辑:

很抱歉没有看到上面的签名!看起来您只是缺少了InvokeIfRequired:

的通用参数
ControlExtensions.InvokeIfRequired<string>((value) => { _mw.tb_w1.Text = value; }, godz);

应该可以了:)

另一种方法是调用非泛型方法并捕获委托作用域中的字符串变量:

ControlExtensions.InvokeIfRequired(() => { _mw.tb_w1.Text = godz; });

我觉得这样更简洁一些