我在使用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