2014-11-05 62 views
0

我在使用MVVM和WPF的結合方面有點頭疼。我可以處理簡單的事情,但我目前正在努力解決以下問題。與嵌套視圖模型相結合的驗證設計問題

可以說我有一個TravelPlan對象。 TravelPlan有一個Cities對象(基本上是該計劃將按特定順序訪問的所有城市的集合)。

城市是使用動態控件呈現的。它顯示可能城市的下拉框,加號(+)和減號( - )按鈕。無論何時按下+按鈕,都會出現一個新的空白下拉列表供您選擇。

我已經爲TravelPlan創建了一個viewmodel,併爲城市創建了一個單獨的viewmodel(見下文)。我已添加驗證,因此您已有選擇一個城市。

public class CityViewModel : DataErrorInfoViewModel 
{ 
    private readonly IEnumerable<string> _availableCities; 
    private string _selectedCity; 

    public CityViewModel(IEnumerable<string> availableCities) 
    { 
     _availableCities = availableCities; 
    } 

    public string SelectedCity 
    { 
     get { return _selectedCity; } 
     set 
     { 
      _selectedCity = value; 
      RaisePropertyChanged(() => SelectedCity); 
     } 
    } 

    public IEnumerable<string> AvailableCities 
    { 
     get { return _availableCities; } 
    } 

    protected override bool Validate(string propertyName) 
    { 
     var isValid = base.Validate(propertyName); 
     if (MatchesProperty(() => SelectedCity, propertyName)) 
     { 
      isValid = SelectedCity != null; 
     } 
     return isValid; 
    }   
} 

在TravelPlan viewmodel中,我只使用CityViewModel。

private ObservableCollection<CitiesViewModel> _cities; 

在TravelPlan viewmodel中我還實現了+/- 按鈕。他們只需添加或刪除城市視圖模型。

這個效果很好。

但是,我還想添加驗證以查看所選城市的組合是否是唯一的(即,您不能選擇同一城市兩次)。我無法將其添加到單個CityViewModel,因爲一個城市不瞭解所有其他所選城市。

理想情況下,我想在其自己的ViewModel中轉換CityViewModels的ObservableCollection。然後,我可以將唯一的驗證添加到特定的視圖模型。我相信我也可以將動態usercontrols的邏輯移動到該視圖模型。

這將創建以下層次結構:TravelPlanViewModel - CitiesViewModels - CityViewmodel其中每個viewmodel進行其特定驗證。

這是可能的,這是推薦?我想知道人們如何以MVVM的方式解決這個特定的設計問題。 (我知道可以將獨特的驗證移動到TravelPlan視圖模型中,但是我想知道我描述的場景是否可行並且是常見的做法)。

代碼示例高度讚賞!

+0

如果您有多個城市供用戶選擇,您是對的,您必須在比cityViewModel本身更高的級別實施驗證規則。爲此,您可能需要在視圖中較高的下一個XAML圖層上實現ValidationRule。 WPF將調用ValidationRules並自動爲您生成結果。看看這個類http://msdn.microsoft.com/en-us/library/system.windows.controls.validationrule(v=vs.110)。aspx – 2014-11-05 14:13:34

+0

@ user1522548,我意識到這一點。但我在哪裏進行驗證?進入TravelPlanViewModel?或者是創建一個單獨的CitiesViewModel更好的做法? – Sardaukar 2014-11-05 14:15:26

+0

當然,我們還沒有看到CitesViewModel或TravelPlanViewModel建議。如前所述,您必須在CityViewModel位置的下一個容器中實現它。通常,正確的方法是在最接近需求的容器處。換句話說,如果可以在層次結構中將它包含在較低層中,則不要將其置於頂層窗口層。我經常做的一個技巧是創建實現組合行爲的容器。按照您提到的順序,我可能創建一個包含所有需要的CityViewModel的CitesViewModel。 – 2014-11-05 14:30:21

回答

0

這並不是聞所未聞的實現集合視圖模型 - 只是谷歌「CollectionViewModel」看到一些例子。但是,如果你所做的只是添加驗證,那麼我可能不會費心使用它自己的視圖模型來包裝集合。我只是將唯一性驗證添加到根視圖模型中,因爲約束似乎與TravelPlan更強相關。

所以,是的,這是可能的。我不知道如何共同它是;我個人不這樣做,但至少有一些人有。

+0

我認爲你是正確的驗證,但是,添加和刪除CityViewModel的命令不應該擁有自己的視圖模型嗎? – Sardaukar 2014-11-05 14:20:22

+0

他們肯定可以,取決於這樣做的規則是否足夠普遍,可以重複使用。 – 2014-11-05 14:44:02