我在使用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視圖模型中,但是我想知道我描述的場景是否可行並且是常見的做法)。
代碼示例高度讚賞!
如果您有多個城市供用戶選擇,您是對的,您必須在比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
@ user1522548,我意識到這一點。但我在哪裏進行驗證?進入TravelPlanViewModel?或者是創建一個單獨的CitiesViewModel更好的做法? – Sardaukar 2014-11-05 14:15:26
當然,我們還沒有看到CitesViewModel或TravelPlanViewModel建議。如前所述,您必須在CityViewModel位置的下一個容器中實現它。通常,正確的方法是在最接近需求的容器處。換句話說,如果可以在層次結構中將它包含在較低層中,則不要將其置於頂層窗口層。我經常做的一個技巧是創建實現組合行爲的容器。按照您提到的順序,我可能創建一個包含所有需要的CityViewModel的CitesViewModel。 – 2014-11-05 14:30:21