绑定属性并不总是更新到控件

时间:2015-09-22 18:20:05

标签: c# wpf xaml data-binding

我的视图模型中有以下代码。它有三种不同的状态,让我感到困惑的是,第一个和最后一个状态显示在控件中,但进展没有。

public void DoStuffForAWhile(int limit)
{
  TheBoundProperty = "This is not shown.";

  DateTime start = DateTime.Now;
  TimeSpan elapsed;
  do
  {
    elapsed = new TimeSpan(DateTime.Now.Ticks - start.Ticks);
    TheBoundProperty = "Neither is this.";
  } while (elapsed.TotalSeconds < limit);

  TheBoundProperty = "But this is!";
}

正确设置了绑定,因为我在创建视图模型时看到了起始文本。我看到更新程序的最后一个文本。此外,属性的set方法被命中,值是未显示的字符串。

有关未显示值的原因的任何提示?如何解决问题?

2 个答案:

答案 0 :(得分:2)

这是因为所有普通代码都在主UI线程上的DispatcherPriority.Normal运行,所有渲染代码都在DispatcherPriority.Render运行,public void DoStuff() { TheBoundProperty = "Loading .."; Task.Factory.StartNew(() => { RunSomething(); }) .RunWorkerCompleted(() => { TheBoundProperty = "Load Completed"; }); } 的代码较低。

.Normal运行的所有东西都会在.Render之前执行,所以当UI更新时,只有最终的消息就在那里。

您要做的是将字符串设置为加载,然后启动另一个线程来执行长时间运行的进程。一旦长时间运行的过程完成,您需要再次更新标签。

我希望您的最终代码看起来像这样:

private void UpdateLoadingLabel(int percent)
{
    Application.Dispatcher.BeginInvoke(DispatcherPriority.Background,
    new Action(delegate() { 
         TheBoundProperty = string.Format("Loading {0}/100..", percent);
     }));
}

如果您想定期更新,我希望使用调度程序将更新发送到主UI线程。

Notification

我并不完全确定我有这一切的语法,但你应该明白这一点。有关此示例代码的更详细说明,请查看priority list

答案 1 :(得分:1)

使用延迟。

for(std::map<int, int>::iterator itr = map.begin(); itr != map.end(); itr++) {} //or
for(auto itr = map.begin(); itr != map.end(); itr++) {}

<强>更新

如果你坚持使用任务..

public async void DoStuffForAWhile(int limit)
{
  TheBoundProperty = "This is not shown.";

  DateTime start = DateTime.Now;
  TimeSpan elapsed;
  do
  {
    elapsed = new TimeSpan(DateTime.Now.Ticks - start.Ticks);
    TheBoundProperty = "Neither is this.";
    await Task.Delay(1000); //1 sec delay
  } while (elapsed.TotalSeconds < limit);

  TheBoundProperty = "But this is!";
}

但完全没必要使用Task或Dispatcher