[英]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.