具有复杂模型的MVVM

时间:2017-01-04 09:17:15

标签: c# wpf mvvm

当使用MVVM模式时,当Model对象变得复杂时,即当它们包含非原始/非内置属性时,我会遇到麻烦。在我的特定实例中,我有一个ModelA,其中包含ModelB个对象的集合,这些对象本身包含ModelC个对象的集合:

class ModelA
{
    public string Name { get; set; }
    public OberservableCollection<ModelB> Bs { get; set; }
}

class ModelB
{
    public string Make { get; set; }
    public ObservableCollection<ModelC> Cs { get; set; }
}

class ModelC
{
    public string Brand{ get; set; }
}

我有一个ModelAViewModel,允许访问ModelB Bs属性的集合。在这种情况下,我没有为ViewModel创建ModelB。我使用ModelB s设置了ModelCDataTemplate个集合(以及各个实例)的样式:

<DataTemplate x:Key="modelATemplate">
    <Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition />
        </Grid.RowDefinitions>
        <ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
            <ItemsControl  ItemsSource="{Binding Bs}" ItemTemplate="{StaticResource modelBTemplate}"/>
        </ScrollViewer>
    </Grid>
</DataTemplate>

<DataTemplate x:Key="modelBTemplate">
    <Grid Margin="5" HorizontalAlignment="Center">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="{Binding Make}">
        <ItemsControl Grid.Row="1" ItemsSource="{Binding Mode=OneWay, Path=Cs}"
                  ItemTemplate="{StaticResource ResourceKey=modelCTemplate}">
        </ItemsControl>
    </Grid>
</DataTemplate>

我被告知这不是MVVM的做事方式,而且每个实体,即ModelBModelC应该有自己的ViewModel。我被告知要保留Model类,但为他们创建ViewModel。我无法想象这是如何发挥作用的。

如果我创建ModelBViewModel

public class ModelBViewModel
{
     ModelB MyModelB { get; set; }
}

我有一个困境 - 我已在ModelB课程中拥有ModelA个实例,我现在在ModelB中有其他ModelBViewModel个实例。是否有必要在ModelB内遍历原始ModelA集合并创建ModelBViewModel s,将MyModelB属性设置为与ModelA中的java.io.FileNotFoundException: C:\Users\sswain\.m2\repository\com\sun\xml\bind\jaxb-xjc\2.2.4-1\jaxb-api.jar (The system cannot find the file specified) at java.util.zip.ZipFile.open(Native Method) ~[na:1.8.0_45] at java.util.zip.ZipFile.<init>(ZipFile.java:220) ~[na:1.8.0_45] at java.util.zip.ZipFile.<init>(ZipFile.java:150) ~[na:1.8.0_45] at java.util.jar.JarFile.<init>(JarFile.java:166) ~[na:1.8.0_45] at java.util.jar.JarFile.<init>(JarFile.java:130) ~[na:1.8.0_45] at org.apache.tomcat.util.scan.JarFileUrlJar.<init>(JarFileUrlJar.java:60) ~[tomcat-embed-core-8.5.6.jar:8.5.6] at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:48) ~[tomcat-embed-core-8.5.6.jar:8.5.6] at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:338) ~[tomcat-embed-core-8.5.6.jar:8.5.6] at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:288) ~[tomcat-embed-core-8.5.6.jar:8.5.6] at org.apache.jasper.servlet.TldScanner.scanJars(TldScanner.java:262) [tomcat-embed-jasper-8.5.6.jar:8.5.6] at org.apache.jasper.servlet.TldScanner.scan(TldScanner.java:104) [tomcat-embed-jasper-8.5.6.jar:8.5.6] at org.apache.jasper.servlet.JasperInitializer.onStartup(JasperInitializer.java:101) [tomcat-embed-jasper-8.5.6.jar:8.5.6] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178) [tomcat-embed-core-8.5.6.jar:8.5.6] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.5.6.jar:8.5.6] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403) [tomcat-embed-core-8.5.6.jar:8.5.6] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) [tomcat-embed-core-8.5.6.jar:8.5.6] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_45] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45] at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45] 属性相匹配?什么应该相当简单似乎有点复杂?

1 个答案:

答案 0 :(得分:1)

MVVM意味着&#34;模型视图ViewModel&#34;。如您所见,该名称包含Model和ViewModel。我们的想法是为您拥有的每个Model类都有一个专用的ViewModel类。

ViewModel应包含特定于视图的属性和逻辑,而Model类应包含业务模型特定属性和逻辑。

并且:是的,对于一些非常简单的MVVM示例,这可能是开销。但是,只要您的视图逻辑开始偏离业务逻辑,您就会从这个分离中受益。

如果有必要迭代原始属性:我会说:是的! 我通常这样做:

public class ModelBViewModel
{
    private ModelB _model;

    public ObservableCollection<ModelCViewModel> CVms { get; set; }

    public ModelBViewModel(ModelB model) {
        _model = model;
        CVms = new ObservableCollection();
        foreach(var modelC in model.Cs) {
            CVms.Add(new ModelCViewModel(modelC));
        }
    }
}