在分层数据结构中为 MVVM 添加编辑

发布于 2024-09-11 18:14:30 字数 1310 浏览 3 评论 0原文

这个问题是这个旧问题的后续问题,这更像是一种确认,而不是一个悬而未决的问题。

我的 ViewModel 实例有一个模型的私有实例,_modelInst
ViewModel 在编辑期间可以独占访问 Model 的数据(因此 Model 不需要实现 INotifyPropertyChanged)。

现在,我想出了三种从视图编辑模型数据的方法:

  1. 直接在模型实例上获取/设置
    例如简单值字段
    return _modelInst.fieldname;
    _modelInst.fieldname = value;
    这个很容易实现...

  2. 创建一个 ViewModel 实例并在父级的数据结构上进行操作
    例如,对于更复杂的对象类型,例如结构

    • 为该类型创建一个新的 ViewModel。
      ViewModel 知道父级及其字段名称。
    • 在 ContentControl+DataTemplate 中显示该内容
    • 获取/设置:
      通过以字段名作为参数的父级方法,
      即使只更改一个字段,也会覆盖整个原始对象

    这意味着为每个结构创建一个由父级实现的新接口(具有在 _modelInst 上工作的更新例程)。

  3. 在不直接了解父级数据结构的情况下创建 ViewModel 实例
    例如,对于父类中的类(列表)

    • 为每个类创建一个新的 ViewModel

    • 通过以下方式向家长发送更新说明

      1. 命令
      2. 消息
      3. 反射(父级知道哪个子级调用了该函数
        通过将实例与所有存储的子实例进行比较)

      所有这些都是一团糟,为以下目的创建函数 模型的每个可编辑字段。
      这意味着模型的几乎所有字段......

(4.) 人们可以创建一个通用的 ViewModel,它仅通过反射工作,其中每个 子对象知道其父对象及其字段名称(+索引,如果在列表中)。
只有根的逻辑才会干扰模型。
但该解决方案还需要一种方法来存储 _modelInst 中字段的路径。

有没有其他(更简单)的方法来实现这一目标?
我是否再次误解了 MVVM 的原理?
MVVM 适合操作大型分层数据结构吗?

This question is a follow-up of this older one, and it's more of a confirmation than an open question.

My ViewModel instance has a private instance of the Model, _modelInst.
The ViewModel has exclusive access to the Model's data during editing (so the Model doesn't need to implement INotifyPropertyChanged).

Now there are three ways I came up with how to edit the Model data from the View:

  1. Getting/setting directly on the Model instance
    e.g. for simple value fields
    return _modelInst.fieldname;
    _modelInst.fieldname = value;
    This one's easy to implement...

  2. Creating a ViewModel instance and operating on the parent's data structure
    e.g. for more complex object types like structs:

    • Creating a new ViewModel for that type.
      The ViewModel knows the parent and its fieldname.
    • displaying that in a ContentControl+DataTemplate
    • getting / setting:
      via methods of the parent with the fieldname as parameter,
      overwriting the whole original object even if only one field is changed

    This means creating a new interface (with update routines working on _modelInst), implemented by the parent, for each of these structures.

  3. Creating ViewModel instances with no direct knowledge of the parent's data structure
    e.g. for (lists of) classes within parent classes

    • Creating a new ViewModel for each class

    • Sending update instructions to the parent via

      1. commands
      2. messages
      3. reflection (parent knows which child called the function
        by comparing the instance to all stored children)

      All of these are a big mess implementing, creating functions for
      every field of the model that is editable.

      Which means pretty much all fields of the model...

(4.) One could create a generic ViewModel which works via reflection alone, where each
subobject knows its parent and its fieldname (+index, if in a list).
Only the root's logic would then interfere with the model.
But that solution would also require a means to store the path to a field within _modelInst.

Is there any other (more simple) way to achieve this?
Did I misunderstand the principles of MVVM (again)?
Is MVVM suited for manipulation of large hierarchical data structures?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

维持三分热 2024-09-18 18:14:30

希望这些资源能有所帮助;当我学习 MVVM 以及如何使用视图模型表示对象图/层次结构时,它们对我帮助很大:

  1. 可编辑对象适配器
  2. 可编辑集合适配器
  3. 微模型

Hopefully these resources will help; they helped me quite a bit as I learned MVVM and how to approach representing object graphs/hierarchies with view models:

  1. Editable Object Adapter
  2. Editable Collection Adapter
  3. MicroModels
听,心雨的声音 2024-09-18 18:14:30

这是一个很好的问题,我认为 MVC 模式没有一个很好的答案。

当 ViewModel 映射到的模型没有子项时,它会很好地工作。

但是当模型有子对象时,就像在

Customer

        -->Order

        -->Country

中一样(想象 Country 是 Customer 的子对象),设计模式就会崩溃。

我发现最好的事情是使用继承并有选择地公开
仅那些您需要视图模型逻辑的子项。否则,只需访问
将通过继承传入的视图的模型属性。

public class CustomerView : Customer //继承自Customer(模型)
{

public CustomerView(Customer customer)
{
      this.FirstName = customer.FirstName
      //etc..

      //Only if you need it, that is if you have some display-specific
      //logic relating to country for a given view, you create
      //a CountryView class that inherits from Country and gets populated
      //by an instance of it as well
      this.CountryView = new CountryView(customer.Country)
}

public CountryView CountryView {get;set;} //sadly you cannot override Country but you may be able to shadow it.

public string DisplayColor
{
    if(base.FirstName == "Joe")
    {
        return "red";
    }
    return "";
}

}

与孙辈打交道时,这会变得混乱。如果有人有更好的解决方案,我很想听听。

谢谢

This is an excellent question for which I do not feel there is a good answer that comes stock with the MVC pattern.

ViewModels work great when the model they map to has no children.

But when the model has children, as in

Customer

        -->Order

        -->Country

(imagining Country were a child object of Customer) the design pattern kind of breaks down.

The best thing I've found is to use inheritance and selectively expose
only those children for which you need viewmodel logic. Otherwise, just access
the model's properties of the view that will come in via inheritance.

public class CustomerView : Customer //inherits from Customer (model)
{

public CustomerView(Customer customer)
{
      this.FirstName = customer.FirstName
      //etc..

      //Only if you need it, that is if you have some display-specific
      //logic relating to country for a given view, you create
      //a CountryView class that inherits from Country and gets populated
      //by an instance of it as well
      this.CountryView = new CountryView(customer.Country)
}

public CountryView CountryView {get;set;} //sadly you cannot override Country but you may be able to shadow it.

public string DisplayColor
{
    if(base.FirstName == "Joe")
    {
        return "red";
    }
    return "";
}

}

This gets messy when dealing with grandchildren. If anyone has a better solution, I would love to hear it.

Thanks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文