单击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);
    }
  }
}

单击WPF时更新布局

如果希望标签在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";
    }