从视图访问模型类,无需直接访问模型层 [英] Access a Model class from a View without direct access to Model Layer

查看:42
本文介绍了从视图访问模型类,无需直接访问模型层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 Model 类型的用户控件之一中创建一个 Property,但我认为我必须防止直接访问模型层来自View Layer.

I need create a Property in one of my user controls of a Model type but i think i must prevent direct access to Model Layer from View Layer.

我有一个 ModelView Model,它提供了我的 模型对象集...

I have a View Model of the Model that provide set of my model objects...

  • SetOfA_UserControl
  • SetOfA_ViewModel
  • A_Model

我的用户控件中需要一个像这样的属性:

I need a property Like this in my user control:

public A_Model SelectedA { get; set; }

一种方法是创建一个新的 View Model 如下代码,并在我的 User Control 中使用它:

One way is create a new View Model like following codes and use it in my User Control:

// ------------ View Model Layer ------------

public class SingleA_ViewModel: ModelA
{
}

// --------------- View Layer ---------------

public SingleA_ViewModel SelectedA { get; set; }

但我试图阻止一个新的空视图模型类继承上面的模型.正确吗?

But I'm trying to prevent a new empty view model class that inherit the model like above. is it correct?

您有什么建议可以防止直接访问模型层并在我的用户控件中创建Property???

What is your suggestions to prevent direct access to Model layer and create the Property in my User Control???

编辑 1:

我有 3 个项目:

  • 查看项目
  • 查看模型项目
  • 模型项目

我想知道我是否可以在 View project 中阻止对 Model project 的引用....

I want know can i prevent reference to Model project in View project or not....

我的视图模型中也有一个 SelectedA 属性,我将逻辑放在 View 模型类 中,它在我的视图中运行良好但是 我的 UserControl 中还有一个 SelectedA 属性,我将它绑定到我的 ViewModel 类中的 SelectedA 属性... 但是我需要直接访问 UserControl 中的 Model 来定义这个属性!

I have a SelectedA property in my View Model too and i put my logic in View model class and it work well in my view but also i have a SelectedA Property in my UserControl that i bind it to SelectedA property in my ViewModel class... But i need direct access to Model in UserControl to define this property!

当我可以从 View 直接访问 Model 时,我的代码是这样的:

When i have a direct access to Model from View my codes is like this:

// ------------ Model Layer ------------
public class AModel
{
}

// ------------ View Model Layer ------------
public class SetOfA_ViewModel: INotifyPropertyChanged
{
    public AModel SelectedA { get; set; }

    public ObservableCollection<AModel> Items
    {
        get { return _items; }
        set
        {
            _items = value;
            OnPropertyChanged("Items");
        }
    }

    // Other Logic codes to fill and keep SelectedA value and....
}



// --------------- View Layer ---------------
public partial class MyUserControl : UserControl
{
    public AModel SelectedA { 
    get { return (AModel)GetValue(SelectedAProperty); }
        set
        {
            var oldValue = (AModel)GetValue(SelectedAProperty);
            if (oldValue != value) SetValue(SelectedAProperty, value);
        }
    }

    public static readonly DependencyProperty SelectedAProperty =
        DependencyProperty.Register(
            "SelectedA",
            typeof(AModel),
            typeof(MyUserControl),
            new PropertyMetadata(OnSelectedAValueChanged));

    public MyUserControl ()
    {
        InitializeComponent();

        const string NAME_OF_PROPERTY_IN_VM = "SelectedA";
        var binding = new Binding(NAME_OF_PROPERTY_IN_VM) { Mode = BindingMode.TwoWay };
        this.SetBinding(SelectedAProperty, binding);
    }

    private static void OnSelectedAValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        //------
    }  
}

上述方法对我来说效果很好,我现在使用它但是我正在尝试在我的 View 中删除对 Model Project 的任何直接访问和引用Project 那么我如何在我的 user control 中实现 AModelSelectedA 依赖属性?

The above method work well for me and i use this now BUT I'm trying to Delete any direct access and reference to Model Project in my View Project then how can i implement the SelectedA dependency property of AModel in my user control?

有朋友说可以直接从view project访问model project.我想知道正确的方法 可能的方法...!

Some friends say you can access model project directly from view project. i want know Correct ways, NOT possible ways...!

编辑 2

当我将 SelectedA 项保留在我的用户控件中时,然后像这样在我的窗口中使用它:

When i keep SelectedA item in my user control then use it in my window like this:

<userControls:MyUserControl x:Name="MyUserControl1"/>

<Label Content="{Binding ElementName=MyUserControl1, Path=SelectedA.Title}" />

<小时>

编辑 3

为什么我要阻止从 ViewModel 直接访问模型?

我搜索了 MVVM 图,但没有找到从视图到模型的直接访问.所有图表都说:

I searched about MVVM diagrams and did not find and direct access from View to Model. all the diagrams says:

.........

现在我们可以直接从视图访问模型了吗?

  • 为什么有很多示例可以直接访问 Web 上的 View 中的模型?

  • Why there are many samples that have direct access to model in View on the web?

为什么有些人说你可以做到这一点?

And why some people say you can do this?

如果我们能做到这一点并且直接访问模型是一个正确的实现,为什么上图中的视图和模型之间没有任何关系???

If we can do this and direct access to model is a correct implement why there is not any relation between View and Model in the above diagrams???

推荐答案

视图模型不是模型,因此不应派生.

A viewmodel is not a model so it should not derive.

如果您决定将视图与模型耦合,模型中通常由外部源决定的任何更改都可能影响使用它的视图.

If you decide to couple the view to the model, any change in the model which is often dictated by an external source, might affect the views it is used in.

当为每个视图使用视图模型时,某些视图可能根本不会受到更改的影响,受影响的视图可以通过调整视图或在视图模型中编写代码来修复.

When using a viewmodel for each view some views might not be affected at all by the change and affected views can be fixed by either adjusting the view or by writing code in the viewmodel.

是的,在两者之间添加一个额外的层是额外的工作,但它也带来了从视图到模型再返回的清晰点.经过几次增量后,它可能是值得的.

Yes, adding an extra layer in between is extra work but it also comes with a clear point of transitioning from view to model and back again. After a couple of increments it might be worth it.

额外的层还为命令和验证以及查看特定属性提供了一个很好的扩展点.

The extra layer also provides a nice point of extension for commands and validation and view specific properties.

如果您决定将模型作为视图模型的属性公开,那么将特定于视图的属性和命令添加到模型中会变得非常诱人.它们会很快污染模型,使模型难以重复使用或再生.

If you decide to expose the model as a property of the viewmodel it can become very tempting to add properties and commands to the model that are view specific. They will pollute the model quickly and make the model hard to be reused or regenerated.

没有法律,也没有警察.考虑我的论点并选择一个选项.尝试开放以稍后更改您的设计.现在看起来很容易的事情以后可能会变得困难.我们不知道会发生什么;敏捷/灵活.根据我的经验,我发现对于可以使用多个版本的应用程序,模型和视图模型之间的清晰分离会更有效,但对于短期应用程序来说,它可能太多了.

There is no law and there is no police. Take my arguments into consideration and pick an option. Try to be open to change your design later. What appears to be easy right now might become difficult later on. We don't know what will happen; be agile/flexible. In my experience I found that for applications that survive many versions it was more efficient to have a clean separation between model and viewmodel but for short lived apps it might be too much.

在实现 MVVM 模式时,我总是确保模型不知道或假设有关视图模型的任何信息,并且视图模型不了解或假设有关视图的任何信息.视图模型是中间的人;它知道从哪里获取模型的实例以及从哪里发送模型的更改.我多次使用一个或多个知道如何获取或保存模型实例的存储库,因此视图模型只需要知道存储库.存储库可以处理或委托其他功能,例如跨视图模型实例缓存.

When implementing the MVVM pattern I always make sure that the model doesn't know or assume anything about the viewmodel and the viewmodel doesn't know or assume anything about the view. The viewmodel is the man in the middle; it knows where to get instances of the model and where to send changes of the model. many times I have used one or more repositories that know how to get or save model instances so the viewmodel only has to know about the repository. The repository can take care or delegate other features such as caching across viewmodel instances.

一般来说,我为每个视图创建一个视图模型,并将视图模型的一个实例分配给视图的数据上下文.所有绑定路径(对于属性和命令)都是相对于该视图模型的.

In general I create one viewmodel per view and I assign an instance of the viewmodel to the datacontext of the view. All binding paths (for both properties and commands) are relative to that viewmodel.

有时我通过向主视图模型添加属性来嵌套视图模型,这些属性本身就是视图模型.

Sometimes I nest viewmodels by adding properties to the main viewmodel that are viewmodels themselves.

这篇关于从视图访问模型类,无需直接访问模型层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆