我有一个简单的页面,上面有一个按钮和一个标签。当我单击按钮时我想要更新标签文本,我已经复制了here
中的代码然而,当我使用以下示例时。在功能完成之前,文本不会更新。有任何想法吗。 WPF窗口表格上有按钮和标签。
我在按钮按下后的代码中有以下内容,并且永远不会显示第一条消息。
Thread.Sleep表示从数据库中提取数据以返回到屏幕,这可能需要3到30秒的时间,因此我想让它能够向用户展示一些东西。
任何想法???
using System.Threading;
using System.Windows;
using System.Windows.Threading;
namespace NetSpot.RESV4.Presentation
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
label1.Content = "Button 1 Clicked";
ForceUIToUpdate();
Thread.Sleep(4000);
label1.Content = "button 1 Updated";
}
public static void ForceUIToUpdate()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new DespatcherOperationCallback(delegate(object parameter)
{
frame.Continue = false;
return null;
}), null);
Dispatcher.PushFrame(frame);
}
}
}
答案 0 :(得分:3)
如果您希望标签在4秒后更新,那么使用Dispatcher Timer可能会更好。
public partial class Window1 : Window
{
readonly DispatcherTimer m_timer = new DispatcherTimer();
public Window1()
{
InitializeComponent();
m_timer.Interval = TimeSpan.FromSeconds(4);
m_timer.Tick += TimerOnTick;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
label1.Content = "Button 1 Clicked";
m_timer.Start();
}
private void TimerOnTick(object sender, EventArgs eventArgs)
{
m_timer.Stop();
label1.Content1 = ...
}
答案 1 :(得分:2)
要直接回答您的问题(无论采用何种方法),您都不会在初始值更改后发信号通知UI应该更新。点击事件结束后,此信号自动发生。添加对label1.UpdateLayout()
的调用,如下所示:
private void button1_Click(object sender, RoutedEventArgs e)
{
label1.Content = "Button 1 Clicked";
label1.UpdateLayout();
ForceUIToUpdate();
Thread.Sleep(4000);
label1.Content = "button 1 Updated";
}
现在您应该看到预期的行为。
编辑 - 尝试使用此版本的ForceUIToUpdate。
public static void ForceUIToUpdate()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Render, new DispatcherOperationCallback(delegate(object parameter)
{
frame.Continue = false;
return null;
}), null);
Dispatcher.PushFrame(frame);
}
这会导致ForceUIToUpdate阻塞,直到帧通过渲染队列,这就是你真正想要的。
答案 2 :(得分:0)
尽量不要让当前线程进入睡眠状态,而只是通过调度程序设置另一个线程的值。
private void button1_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>
{
Dispatcher.Invoke(new Action(() =>
{
label1.Content = "Waiting";
}), null);
Thread.Sleep(2000);
Dispatcher.Invoke(new Action(() =>
{
label1.Content = "Done";
}), null);
});
}
希望这有帮助。
更新:使用async / await
private async void button1_Click(object sender, RoutedEventArgs e)
{
label1.Content = "Waiting";
await Task.Run(() => Thread.Sleep(2000));
label1.Content = "Done";
}