我在.NET 3.5和Visual Studio 2008下有一个WPF MVVM应用程序。视图中的一些控件绑定到视图模型的属性,所以当这些属性发生变化,它将通过INotifyPropertyChanged的实现通知给视图。MVVM:在完成WPF NET 3.5中的线程池工作项后更新视图的控件可见性
我开始时会在窗口中央出现一些说“正在加载...”的闪屏,并且在从数据库请求某些数据时它会保持可见状态。一旦从数据库请求数据,我想要隐藏这种飞溅。
此飞溅在视图模型中绑定到一个属性“IsSplashVisible”,因此将属性更新为true,通知在beginnig中显示的飞溅并将其设置为false,通知要隐藏的飞溅。
在开始时将属性“IsSplashVisible”设置为true是没有问题的,当排队的工作项目完成时将属性设置为false时会出现问题。一旦将此属性设置为false,将通知控件(splash“正在加载...”),并尝试隐藏但失败,因为这是创建它的人的不同线程,因此引发了典型的异常。那我该如何解决这个问题?
下面的代码。
视图模型:
public class TestViewModel : BaseViewModel
{
private static Dispatcher _dispatcher;
public ObservableCollection<UserData> lstUsers
public ObservableCollection<UserData> LstUsers
{
get
{
return this.lstUsers;
}
private set
{
this.lstUsers= value;
OnPropertyChanged("LstUsers");
}
}
private bool isSplashVisible = false;
public bool IsSplashVisible
{
get
{
return this.isSplashVisible;
}
set
{
if (this.isSplashVisible== value)
{
return;
}
this.isSplashVisible= value;
OnPropertyChanged("IsSplashVisible");
}
}
public TestViewModel()
{
this.IsSplashVisible = true;
ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
{
var result = getDataFromDatabase();
UIThread(() =>
{
LstUsers = result;
this.IsSplashVisible = false; <---- HERE IT FAILS
});
}));
}
ObservableCollection<UserData> getDataFromDatabase()
{
return this.RequestDataToDatabase();
}
static void UIThread(Action a)
{
if(_dispatcher == null) _dispatcher = Dispatcher.CurrentDispatcher;
//this is to make sure that the event is raised on the correct Thread
_dispatcher.Invoke(a); <---- HERE EXCEPTION IS THROWN
}
}
像@Clemens说,在你的代码把'Application.Current.Dispatcher'纳入这一点,所以它看起来像这样'如果(_dispatcher == NULL)_dispatcher = Application.Current.Dispatcher;' – XAMlMAX
@ XAMlMAX除了根本不具备该领域的意义。 *更好*总是调用'Application.Current.Dispatcher.Invoke(...)'。 – Clemens
虽然它可能很牵强,但理论上可以在两个不同的UI线程中创建两个视图模型实例。然后,一个静态的Dispatcher字段将无法正常工作。 – Clemens