我對MVVM相對來說比較新,我想爲MVVM WPF應用程序編寫一個基本狀態欄。我認爲我有一些東西的要點,但出於某種原因,狀態欄並不總是更新,我不知道爲什麼。StatusBar並不總是更新
在我的ViewModel,我有更新的基本屬性,當我改變的狀態消息:
public string StatusMessage
{
get { return _statusMessage; }
set
{
if (value == _statusMessage) return;
_statusMessage = value;
base.OnPropertyChanged(() => this.StatusMessage);
}
}
我OnPropertyChanged方法(我在實現INotifyPropertyChanged基ViewModel類)看起來像這樣(得到了岡瑟Foidl這個想法,希望我能居功,因爲我認爲這是華而不實的,但我不是很聰明):
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> exp)
{
MemberExpression me = exp.Body as MemberExpression;
string propName = me.Member.Name;
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propName));
}
}
無論如何,這一切都爲我所有的控件的偉大工程,除了一。在我MainWindow.xaml文件,我有一個綁定到上述財產,像這樣一個StatusBarItem控制(XAML的其餘部分被剪短空間原因):
<StatusBarItem Grid.Column="0">
<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding Path=StatusMessage}" />
</StatusBarItem>
當我運行我的應用程序(它擊中幾個數據庫除了從模板和其他相當資源密集的東西中生成一個文檔之外),一些但不是全部的消息顯示在狀態欄上。我已經調試並驗證了這些消息全部進入了上面的StatusMessage屬性(和隨後的私有變量),但它們似乎並沒有在UI中刷新。
我看了幾個使用ProgressBar控件的BackgroundWorker實例的例子,但沒有看到任何StatusBarItem控件,並且我不確定如何將一個轉換爲另一個。我已經在之前的C#4.0和WPF應用程序中使用了任務,並且認爲它可能是一個很好的方法,但我還沒有真正弄清楚如何/在哪裏指定UI任務(我稱之爲「我以前總是在MainWindow的代碼隱藏中做到這一點,但我正在努力爭取一個零代碼保持與MVVM保持一致)。
我非常肯定,多線程方法是要走的路;我只是不太瞭解一種方法(我知道一點這個和一點點)以使其工作。我確實看到一些直接使用舊的線程方法的帖子,但是我幾乎不用多線程編程,直到我開始使用.NET 4.0的任務(發現它們更易於理解和跟蹤),所以我有有點麻煩使他們感覺。
任何人都可以憐憫我,並指出我在正確的方向,或建議進一步的調試,我可以做什麼?謝謝!
我有類似的更新TextBlock問題,你到底找到了解決方案嗎? – 2011-06-14 08:01:57
我**能夠通過將我的UI TaskScheduler傳遞到ViewModel並對從所述調度程序生成的任務執行更新來獲得任務代碼的工作。如果時間允許,我會在單獨的答案中發佈代碼示例。 – 2011-06-17 12:10:41
@Julien,這就是我所做的。當我在我的App.xaml.cs文件中初始化我的ViewModel時,我傳入了兩個TaskFactory實例:一個用於UI:新的TaskFactory(TaskScheduler.FromCurrentSynchronizationContext())'我調用了'UiTasks',一個用於其他任務'任務.Factory'我稱之爲'DefaultTasks'。然後,我確定我的繁重工作在默認任務工廠下運行,並使用UI工廠更新了我的屬性:'this.UiTasks.StartNew((=)this.StatusMessage = myMessage;});'這似乎是個訣竅。如果你願意,我會很樂意給你一個更詳細的例子。祝你好運! – 2011-06-19 14:04:04