繁体   English   中英

如何更新WPF MainWindow上的控件

[英]How to update a control on WPF MainWindow

如何在下面的代码中更新我的label1文本? 我得到一个“调用线程无法访问此对象,因为不同的线程拥有它”错误。 我已经读过其他人使用过Dispatcher.BeginInvoke,但我不知道如何在我的代码中实现它。

public partial class MainWindow : Window
{
    System.Timers.Timer timer;

    [DllImport("user32.dll")]        
    public static extern Boolean GetLastInputInfo(ref tagLASTINPUTINFO plii);

    public struct tagLASTINPUTINFO
    {
        public uint cbSize;
        public Int32 dwTime;
    }

    public MainWindow()
    {
        InitializeComponent();
        StartTimer();
        //webb1.Navigate("http://yahoo.com");
    }

    private void StartTimer()
    {
        timer = new System.Timers.Timer();
        timer.Interval = 100;
        timer.Elapsed += timer_Elapsed;
        timer.Start();
    }

    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        tagLASTINPUTINFO LastInput = new tagLASTINPUTINFO();
        Int32 IdleTime;
        LastInput.cbSize = (uint)Marshal.SizeOf(LastInput);
        LastInput.dwTime = 0;

        if (GetLastInputInfo(ref LastInput))
        {
            IdleTime = System.Environment.TickCount - LastInput.dwTime;
            string s = IdleTime.ToString();
            label1.Content = s;
        } 
    }
}

你可以尝试这样的事情:

if (GetLastInputInfo(ref LastInput))
{
    IdleTime = System.Environment.TickCount - LastInput.dwTime;
    string s = IdleTime.ToString();

    Dispatcher.BeginInvoke(new Action(() =>
    {
        label1.Content = s;
    }));
}

在此处阅读有关Dispatcher.BeginInvoke方法的更多信息

您需要从主线程保存Dispatcher.CurrentDispatcher

public partial class MainWindow : Window
{
    //...
    public static Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
    //...
}

然后,只要您需要在主线程的上下文中执行某些操作,您就可以:

MainWindow.dispatcher.Invoke(() => {
   label1.Content = s;
});

注意,与Dispatcher.Invoke不同, Dispatcher.BeginInvoke是异步执行的。 你可能想在这里进行 同步调用 对于这种情况,异步调用似乎没问题,但通常您可能想要更新主要的UI,然后继续在当前线程上知道更新已完成。

这是一个类似的问题,有一个完整的例子。

有两种方法可以解决此问题:

首先,您可以使用DispatcherTimer类而不是Timer类,如本MSDN文章中所示 ,该文章修改了Dispatcher线程上Elapsed事件中的UI元素。

其次,使用现有的Timer类,可以使用Dispatcher.BegineInvoke()方法,如下面的timer_Elapsed事件中的代码:

label1.Dispatcher.BeginInvoke(
      System.Windows.Threading.DispatcherPriority.Normal,
      new Action(
        delegate()
        {
          label1.Content = s;
        }
    ));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM