我在.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