使用Thread.Sleep()时Wpf标签未更新

我有一个标签我想在每秒后更新的内容,3秒后我只看到最后一个字符串“第3步……”我做错了什么,如果出于某种原因还有另一种方法来实现这一点我不能使用Thread.Sleep():

视图:

     

查看型号:

 using System.Collections.ObjectModel; using System.ComponentModel; using System.Threading; namespace WpfApplication1.Scroller { public class Message { public Message(string _text) { text = _text; } private string text; public string Text { get { return text; } set {text = value;} } } public class ScrollerViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public DelegateCommand AddNew { get; protected set; } ObservableCollection _messages = new ObservableCollection(); public ObservableCollection Messages { get { return _messages; } set { _messages = value; OnPropertyChanged("Messages"); } } public ScrollerViewModel() { AddNew = new DelegateCommand(Add); } private void Add(object parameter) { UpdateProgress("Step 1..."); UpdateProgress("Step 2..."); UpdateProgress("Step 3..."); } private void UpdateProgress(string step) { Messages.Clear(); Messages.Add(new Message(step)); Thread.Sleep(1000); } protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } } 

这是因为你正在UI线程中睡觉。 在完成添加之前,UI将无法更新。 您可以将BackgroundWorker与ReportProgress一起使用来实现您的目的。 像这样的东西:

 BackgroundWorker worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += delegate(object s, DoWorkEventArgs args) { worker.ReportProgress(1, "Step1"); Thread.Sleep(1000); worker.ReportProgress(2, "Step2"); Thread.Sleep(1000); worker.ReportProgress(3, "Step3"); }; worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args) { string step = (string)args.UserState; Messages.Clear(); Messages.Add(new Message(step)); }; worker.RunWorkerAsync(); 

执行DoWork时不会占用UI线程,但ProgressChanged的代码将在UI线程上执行。

当你在UI线程上时,你永远不应该调用Thread.Sleep。 这将阻止Dispatcher并且不会渲染。 在此期间将发生绑定更新等。

如果要在UpdateProgress()调用之间等待,请使用DispatcherTimer。

您正在清除消息,然后再添加新消息。

 private void UpdateProgress(string step) { Messages.Clear(); // <- Why? Messages.Add(new Message(step)); Thread.Sleep(1000); }