我的视图模型中有以下代码。它有三种不同的状态,让我感到困惑的是,第一个和最后一个状态显示在控件中,但进展没有。
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方法被命中,值是未显示的字符串。
有关未显示值的原因的任何提示?如何解决问题?
答案 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