while循环中更改的标签不会更新UI

时间:2014-08-20 21:47:24

标签: c# wpf loops

运行此代码时:

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循环时,它可以工作,但它不会更新标签......那么如何在没有任何用户输入的情况下更新标签以显示当前时间? 谢谢, →

5 个答案:

答案 0 :(得分:8)

问题是你正在阻止你的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两次。

答案 1 :(得分:1)

您可以使用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());
}

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

答案 2 :(得分:0)

您无法阻止用户界面。 UI线程需要继续传送消息。您可以使用简单的TaskBeginInvoke来实现您的目标。

    public MainWindow()
    {
        InitializeComponent();

        Task.Run(() =>
        {
            while (true)
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    var dtCurrentTime = DateTime.Now;
                    label1.Content = dtCurrentTime.ToLongTimeString();
                }));
                Thread.Sleep(1000);
            }
        });
    }

答案 3 :(得分:0)

是的,你正在阻止主线程,使用像这样的计时器

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 :(得分:-4)

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