2011-06-13 66 views
2

我對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的任務(發現它們更易於理解和跟蹤),所以我有有點麻煩使他們感覺。

任何人都可以憐憫我,並指出我在正確的方向,或建議進一步的調試,我可以做什麼?謝謝!

+0

我有類似的更新TextBlock問題,你到底找到了解決方案嗎? – 2011-06-14 08:01:57

+0

我**能夠通過將我的UI TaskScheduler傳遞到ViewModel並對從所述調度程序生成的任務執行更新來獲得任務代碼的工作。如果時間允許,我會在單獨的答案中發佈代碼示例。 – 2011-06-17 12:10:41

+0

@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

回答

3

1)基於反射的綁定有時可能是內聯錯誤的根源。嘗試看看如果notifyproperty與簡單的字符串而不是反射更改會發生什麼。2)如果你正在使用多線程,那麼你有可能在沒有從UIThread中設置StatusMessage的情況下,它將無法更新UI,你可以在UI Dispatcher上調用setter代碼來查看是否有幫助。

3)檢查結合作品,XAML形式的構造是否修改StatusMessage直接在VM和看到的變化是否在UI顯示而不調用其引入額外的變量,以簡單正文塊多線程服務呼叫 - 串結合

4)如果這沒有幫助你可以創建一個簡單的xaml表單與單個文本塊綁定到您的大viewmodel,看看會發生什麼,如果沒有任何工作,你可以begi ñ切割VM類,使其更簡單,從而結合最終開始工作,你會發現一個錯誤

5)如果你認爲狀態欄的問題是看是否沒有狀態欄單個文本塊(摘錄XAML部分從你的例子)的作品

+0

謝謝,瓦倫丁。事實證明,問題**是**狀態消息沒有從UI線程更新(當時我無法弄清楚如何用MVVM做到這一點)。一旦我能夠在我的App_Startup例程中設置UI TaskScheduler/TaskFactory並將其傳遞到ViewModel的構造函數中,然後使用它產生一個Task來更新狀態,它就像一個魅力一樣工作。謝謝! – 2011-06-17 12:12:52

+0

我很困惑,爲什麼原產線是一個問題。 WPF是打算編組綁定到UI線程上的通知自動不是? – Gusdor 2011-07-27 10:11:16

2

某處通知沒有通過。

我會嘗試:

  • 添加一個虛擬valueconverter上textbinding所以你可以設置一個斷點,看看你被稱爲
  • 在「更好的」時間調度的屬性設置爲設置的值 - 這有時是杞人憂天。

調度該設置可能會訣竅。

相關問題