单击WPF时更新布局
本文关键字:布局 更新 WPF 单击 | 更新日期: 2023-09-27 18:26:24
我有一个简单的页面,上面有一个按钮和一个标签。当我点击按钮时,我想更新标签文本,我已经从这里复制了代码
然而,当我使用以下示例时。在功能完成之前,文本不会更新。任何想法。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);
}
}
}
如果希望标签在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 = ...
}
要直接回答您的问题(无论方法如何),您永远不会向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阻塞,直到帧通过渲染队列,这正是您实际需要的。
尽量不要让当前线程进入睡眠状态,而是简单地通过调度器设置其他线程的值。
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);
});
}
希望这能有所帮助。
更新:使用异步/等待
private async void button1_Click(object sender, RoutedEventArgs e)
{
label1.Content = "Waiting";
await Task.Run(() => Thread.Sleep(2000));
label1.Content = "Done";
}