Shoud视图层知道模型类(实体)?

时间:2018-01-07 20:15:37

标签: c# wpf mvvm

我有一个显示在Pack用户控件上的Shelf实体:

namespace Storage.Model
{
    class Pack
    {
        public string Name { get; set; }
    }
}
<UserControl x:Class="Storage.View.Shelf" ... >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20" />
            <RowDefinition Height="50" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Text="{Binding Path=Name}"/>
        <TextBlock Grid.Row="1" Text="{Binding Path=Capability}"/>
        <ItemsControl Grid.Row="2" ItemsSource="{Binding Path=Packs}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border>
                        <TextBlock Text="{Binding Name}" /> // It's okey ???
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

    </Grid>
</UserControl>
// DataContext for Shelf 
namespace Storage.ViewModel
{
    public class ShelfViewModel
    {
        public string Name { get; set; }
        public string Capability { get; set; }
        public ObservableCollection<Pack> Packs { get; set; }
    }
}

使用MVVM模型可以在DataTemplate我有绑定{Binding Name},因为如果是这样的话:IT&#39;不正确,应该知道关于模型类的知识

2 个答案:

答案 0 :(得分:1)

这取决于您如何定义“模型”。例如,模型可以是对服务或业务层的引用。或者它可能是一个实体对象。

视图完全可以直接绑定到通过视图模型的公共属性公开的实体对象的属性,前提是您实际上可以访问实体类型并且不需要修改以任何方式定义它。

例如,假设Pack是一种包含专有业务逻辑的域类型,并且在您的业务中的几个不同位置使用。您可能根本不想将类等暴露给客户端应用程序。您通常会拥有某种业务层,然后是服务层,它连接到业务层并返回简单的数据传输对象(DTO),而不是包含逻辑的实际业务实体。

只要您不需要执行某些特殊操作(例如向UI提供更改通知),您就可以轻松地直接绑定到此类DTO对象。您需要编写一个包装器(视图模型)类,该类公开底层数据,但也添加了更改通知功能。

因此,如果Pack是一个包含您需要的所有内容的简单公共类型,那么您可以直接使用它。这不违反任何规则。如果是其他内容,则使用特定于客户端或视图的包装类。

答案 1 :(得分:0)

它的编程,所以答案永远是&#34;它取决于&#34;。

如果您的模型具有View所需格式的所有数据且模型是不可变的,那么为什么不实用并直接将模型绑定到View?

但是只要您需要命令,对模型属性进行写访问,在模型和视图之间进行数据转换,或者模型属性是否可以更改(并且您不想在模型上实现INotifyPropertyChanged),你应该在你的模型周围包装一个ViewModel来解决这个问题。