为什么绑定刷新会延迟到委托命令完成为止? (MVVM)
我正在应用 MVVM 模式。我有一个按钮,单击该按钮会在我的 ViewModel 中调用委托命令。在该委托方法的一开始,我设置了一个属性值 (WaitOn),该值应通过显示动画控件来通知用户返回 UI 等待。
但是,在委托完成执行(此时等待已完成)之前,显示该动画控件的绑定不会刷新。为什么会发生这种情况?我应该采取什么措施来解决这个问题?
示例 XAML:
<Button Command="{Binding DoStuffCommand}" />
<ctl:MyAnimatedControl Name="ctlWait" Caption="Please Wait..."
Visibility="{Binding WaitNotification}" />
ViewModel 的代码段:
public bool WaitPart1On
{
get { return _waitPart1On; }
set
{
_waitPart1On = value;
if (_waitPart1On == true)
{
WaitNotification = "Visible";
}
else
{
WaitNotification = "Hidden";
}
RaisePropertyChanged("WaitPart1On");
}
}
public string WaitNotification
{
get { return _waitNotification; }
set
{
_waitNotification = value;
RaisePropertyChanged("WaitNotification");
}
}
public void DoStuff()
{
WaitPart1On = true;
//Do lots of stuff (really, this is PART 1)
//Notify the UI in the calling application that we're finished PART 1
if (OnFinishedPart1 != null)
{
OnFinishedPart1(this, new ThingEventArgs(NewThing, args));
}
WaitPart1On = false;
}
现在从 XAML 进行代码隐藏以捕获引发的事件:
public void Part1FinishedEventHandler(NewThing newThing, ThingEventArgs e)
{
//at this point I expected the WaitPart1On to be set to false
//I planned to put a new wait message up (WaitPart2)
FinishPart2();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
绑定可能正在更新,但由于您在 UI 线程上执行“大量操作”,因此应用程序没有机会更新屏幕。您应该考虑将处理移至后台线程或使用 Dispatcher.BeginInvoke() 以便 UI 可以自由更新和显示等待消息。
在 WPF 中,
Dispatcher
类具有静态 CurrentDispatcher 属性,您可以在 ViewModel 中使用它来安排任务。您的DoStuff
方法如下所示:在 Silverlight 中,您可以使用 Deployment 类:
顺便说一句,您可能需要使用 BooleanToVisibilityConverter,以便您只需要
OnWait
属性进行绑定。此外,即使该属性设置回相同的值,您的 OnWait 设置器当前也会触发通知,您应该像这样实现它:Chances are the binding is being updated, but because you're doing "lots of stuff" on the UI thread, the application isn't getting a chance to update the screen. You should consider moving the processing to a background thread or using
Dispatcher.BeginInvoke()
so that the UI is free to update and display your wait message.In WPF, the
Dispatcher
class has a static CurrentDispatcher property which you can use from within the ViewModel to schedule tasks. YourDoStuff
method would look something like this:In Silverlight, you can access the current dispatcher using the Deployment class:
On a side note, you might want to make use of the BooleanToVisibilityConverter so that you only need the
OnWait
property for the binding. Also, yourOnWait
setter is currently firing notifications even if the property is set back to the same value, you should implement it like this:经过一些调整,我确实让罗里的解决方案发挥了作用。我最终这样做了:
使用“(Action)”创建新的 Action 来包装代码意味着我不必在任何地方声明委托,并且使用“Background”的优先级允许 UI 有机会更新。
I did get Rory's solution working, with a bit of tweaking. I ended up doing this:
Using "(Action)" to create new Action to wrap the code meant I didn't have to declare a delegate anywhere, and using the priority of "Background" allowed the UI its chance to update.