【问题标题】:Label changed in while loop does not update UI在 while 循环中更改的标签不会更新 UI
【发布时间】:2014-08-21 06:20:27
【问题描述】:

运行此代码时:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        while (true)
        {

            InitializeComponent();

            DateTime dtCurrentTime = DateTime.Now;
            label1.Content = dtCurrentTime.ToLongTimeString();
        }
    }

}
}

要经常更新标签,窗口永远不会打开。但是当我删除while循环时它可以工作,但它只是不更新​​标签......那么我将如何更新标签以显示当前时间而无需任何用户输入? 谢谢, 升

【问题讨论】:

标签: c# wpf loops


【解决方案1】:

问题是你阻塞了你的 UI 线程。

您不能以这种方式在 UI 线程上循环运行代码。您需要设置一个Timer,并在计时器中更新您的标签,以允许 UI 线程继续执行和处理消息。

这可能看起来像:

public MainWindow()
{
        InitializeComponent();


        DispatcherTimer timer = new DispatcherTimer 
            {
                Interval = TimeSpan.FromSeconds(0.5)
            };
        timer.Tick += (o,e) =>
            {
                DateTime dtCurrentTime = DateTime.Now;
                label1.Content = dtCurrentTime.ToLongTimeString();
            };
        timer.IsEnabled = true;
}

这将导致计时器每秒更新 UI 两次。

【讨论】:

    【解决方案2】:

    你可以使用Rx:

    using System;
    using System.Reactive.Linq;
    using System.Threading;
    
    public MainWindow()
    {
        InitializeComponent();
        Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))
                  .ObserveOn(SynchronizationContext.Current)
                  .Subscribe(x => Label.Content = DateTime.Now.ToLongTimeString());
    }
    

    您可能不想为此添加依赖项。

    【讨论】:

      【解决方案3】:

      是的,您正在阻塞主线程,请使用这样的计时器

      public partial class Form1 : Form
      {
      
          private Timer timer;
          public Form1()
          {
              InitializeComponent();
      
              timer = new Timer();
              timer.Interval = 1;
              timer.Tick += timer_Tick;
              timer.Enabled = true;
          }
      
          void timer_Tick(object sender, EventArgs e)
          {
              lblTime.Text = DateTime.Now.ToLongTimeString();
          }
      
      }
      

      【讨论】:

        【解决方案4】:

        您可以尝试使用 do...while 循环来完成相同的操作,这将运行代码一次(do 部分),然后继续执行 while 条件。

        【讨论】:

        • -1while (true)do...while(true) 没有什么不同。两者都会创建无限循环。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-06
        • 1970-01-01
        相关资源
        最近更新 更多