如何应用" Model Wrapper VM"用户控件是一个收集孩子?

时间:2014-07-16 09:53:55

标签: wpf mvvm user-controls

我需要为我的模型使用包装器,因为我需要创建一些“View Only”属性,我认为这些属性不适合模型。问题是,它是一个集合成员

这是我的代码片段,可以让事情变得更清晰。 即使我没有完全写下来(缩短代码),但我仍然在我的真实代码中正确使用 INotifyPropertyChanged

这是我的A,B类模型和MainWindowVM:

public class A : INPC
{
    //Some codes
}

public class B : INPC
{
    public ObservableCollection<A> As {get; set;}
}

public class MainWindowVM : INPC
{
    public ObservableCollection<B> Bs {get; set;}
}

这是我的MainWindow代码:

<ItemsControl Grid.Column="0" Grid.Row="0" ItemsSource="{Binding CollectionOfA, Mode=OneWay}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <c:B_UserControl/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

众所周知,“flow”上面的代码是:MainWindowVM(VM) - &gt; B(模型) - &gt; A(型号)

但是,我需要做到:MainWindowVM(VM) - &gt; [BVM(VM) - &gt; B(型号)] - &gt; [AVM(VM) - &gt; A(型号)]

鉴于此AVM和BVM(作为“模型包装器”):

public class AVM : INPC
{
    public A Model {get; set;}

    public AVM (A model) { Model = model; }
}

public class BVM : INPC
{
    public B Model {get; set;}

    public BVM (B model) { Model = model; }
}

怎么做?


我对解决方案的猜测:

改变这个:

public class MainWindowVM : INPC
{
    public ObservableCollection<A> As {get; set;}
}

public class AVM : INPC
{
    public A Model {get; set;}

    public AVM (A model) { Model = model; }
}

public class BVM : INPC
{
    public B Model {get; set;}

    public BVM (B model) { Model = model; }
}

进入:

public class MainWindowVM : INPC
{
    public ObservableCollection<BVM> BVMs {get; set;}
}

public class AVM : INPC
{
    public A Model {get; set;}

    public AVM (A model) { Model = model; }
}

public class BVM : INPC
{
    public B Model {get; set;}
    public ObservableCollection<AVM> AVMs {get; set;} //This is the Binding Property from the UserControl's ItemsControl (code similar to the MainWindow one)

    public BVM (B model) { Model = model; //Then Initialize AVMs, based on Collection of As in B Model }
}

我的回答是否正确,还是有更合适的答案? (不使用 DependencyProperty

1 个答案:

答案 0 :(得分:1)

在数据类型视图模型中包装模型类时,通常会包装每个属性,以便您可以在包装类中实现INotifyPropertyChanged接口。您的模型类应该代表您的业务对象,因此您不应该在那里实现NotifyPropertyChanged接口。因此,您的包装器类看起来更像是这样:

public class AVM : INotifyPropertyChanged
{
    private A model;

    public AVM(A model) { this.model = model; }

    public string SomeStringProperty
    {
        get { return model.SomeStringProperty; }
        set
        {
            model.SomeStringProperty = value;
            NotifyPropertyChanged("SomeStringProperty"); 
        }
    }

    ...
}