2010-09-22 127 views
0

我開始爲我的一個Silverlight應用程序實現MVVM。 (我沒有使用任何工具包)。MVVM viewmodel屬性觸發更新

我的頁面包含有兩個組合框的部分。選擇其中一個組合中的某個項目會觸發一個搜索,用於更新組合框下可見的網格。

每個組合的選定項目都綁定到我的視圖模型中的一個屬性。這些屬性的setter會引發INotifyPropertyChanged屬性更改並自動更新綁定到網格的數據。

一切都很好,直到我需要添加一個重置按鈕,其目的是重置搜索參數即:每個組合框不應該指示任何項目和網格應該是空的。

  • 如果viewmodel中的重置函數更新後備字段,則UI將不會反映更改,因爲不會調用RaisePropertyChanged。
  • 如果視圖模型復位功能更新的屬性,用戶界面將反映這些更改,但網格將被更新兩次:正在重置第一屬性時爲null,也爲第二

任何幫助表示讚賞

/// <summary>Selected user.</summary> 
public User SelectedUser 
{ 
    get { return _selectedUser; } 
    set 
    { 
     _selectedUser = value; 
     RaisePropertyChanged("SelectedUser"); 

     UpdateProducts(); 
    } 
} 

/// <summary>Selected product category.</summary> 
public ProductCategory SelectedProductCategory 
{ 
    get { return _selectedProductCategory; } 
    set 
    { 
     _selectedProductCategory = value; 
     RaisePropertyChanged("SelectedProductCategory"); 

     UpdateProducts(); 
    } 
} 

// Reset option 1 
public void Reset() 
{ 
    _selectedUser = null; 
    _selectedProductCategory = null; 
    _products = null; 
} 

// Reset option 2 
public void Reset() 
{ 
    SelectedUser = null; 
    SelectedProductCategory = null; 
    // No need to update Products which has already been updated twice... 
} 

回答

1

這是真的讓我在很多框架,WPF包括。您需要的是延遲響應更改通知的一些概念,以便用戶永遠不會看到中間狀態。但是,您無法更改WPF對您的通知的響應方式,所以您可以做的最好的做法是延遲您的通知,直到「塵埃落定之後」。就你而言,你需要在發送任何通知之前更改兩個支持字段。

public void Reset() 
{ 
    _selectedUser = null; 
    _selectedProductCategory = null; 
    _products = null; 

    RaisePropertyChanged("SelectedUser"); 
    RaisePropertyChanged("SelectedProductCategory"); 
} 

在我看來,順便WPF同步更新顯示在應對變化的通知,是完全錯誤的:你的復位方法如下編碼這個想法。他們的DependencyProperty系統爲他們提供了一個機會,只需將依賴項標記爲髒,並在稍後進行重新計算。

我使用標記爲骯髒和異步重新計算的想法作爲您在這個問題中注意到的問題的一般解決方案,現在我無法想象沒有它的編程。可惜的是,更多的框架不能以這種方式工作。

+0

感謝您的回答,我同意你的意見。它不僅在理論上是錯誤的,如果我碰巧改變屬性名稱,重構將無法更新關聯的RaisePropertyChanged,如果它們位於一個地方(屬性設置器),但對我來說似乎沒有問題危險的是他們在其他地方可用 – 2010-09-22 09:21:11

+0

不要讓我開始使用字符串的屬性更改通知...哦,如此脆弱和低效。你會認爲微軟定義核心API的人會更聰明一些。 – 2010-09-22 09:26:05

0

如果使用支持字段,你將不得不調用

RaisePropertyChanged("SelectedUser"); 
RaisePropertyChanged("SelectedProductCategory"); 
在reset()方法

+0

謝謝您的回答,那就是我試圖避免:重複RaisePropertyChanged同一屬性。我想在理論上我不應該,但正如你所建議我可能沒有選擇... – 2010-09-22 09:04:55

1

您更新後備字段後,可以提高一個PropertyChanged事件的所有屬性:

RaisePropertyChanged(String.Empty); 
+0

謝謝。這當然會刷新所有的控制,即使那些不關心這些變化的控制。我的整個UI不會「眨眼」? – 2010-09-22 09:27:22

+0

是的,它會刷新與視圖模型綁定的所有內容。但我懷疑你會看到它「眨眼」... – 2010-09-22 09:45:29

相關問題