2014-11-05 38 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