MVVM中的分层数据问题

发布于 2024-08-18 21:18:20 字数 1345 浏览 10 评论 0原文

您认为这个 Model-ViewModel 实现正确吗? 请注意,Stars(在 VM 中)是另一个 VM 内的 VM 的 ObservableCollection,我觉得它将 VM 与 M 解耦,因为当从 Stars 中删除元素时,我仍然必须手动删除它的模型。

关于如何在不使用 OnCollectionChanged 的​​情况下改进这一点的任何想法? 提前致谢。

模型:

public class Galaxy
{
    public Galaxy(string name, IList<Star> stars)
    {
        Name = name;
        Stars = stars;
    }
    public string Name { get; set; }
    public IList<Star> Stars { get; set; }
}

public class Star
{
    public Star(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}

视图模型:

public class GalaxyVM : ViewModelBase
{
    private Galaxy _galaxy;
    private ObservableCollection<StarVM> _stars;

    public GalaxyVM(Galaxy galaxy)
    {
        _galaxy = galaxy;
        _stars = new ObservableCollection<StarVM>(from sys in _galaxy.Stars
                                                  select new StarVM(sys));
    }

    public string Name
    {
        get { return _galaxy.Name; }
    }
    public ObservableCollection<StarVM> Stars
    {
        get { return _stars; }
    }
}

public class StarVM : ViewModelBase
{
    private Star _star;
    public StarVM(Star star)
    {
        _star = star;
    }
    public string Name
    {
        get { return _star.Name; }
    }
}

Do you think this Model-ViewModel implementation is correct?
Note that Stars (in the VM) is an ObservableCollection of VMs inside another one, and i feel like it decouples the VM from the M because when removing an element from Stars, i still have to delete it's model manually.

Any ideas on how to improve this without using OnCollectionChanged?
Thanks in advance.

Models:

public class Galaxy
{
    public Galaxy(string name, IList<Star> stars)
    {
        Name = name;
        Stars = stars;
    }
    public string Name { get; set; }
    public IList<Star> Stars { get; set; }
}

public class Star
{
    public Star(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}

ViewModels :

public class GalaxyVM : ViewModelBase
{
    private Galaxy _galaxy;
    private ObservableCollection<StarVM> _stars;

    public GalaxyVM(Galaxy galaxy)
    {
        _galaxy = galaxy;
        _stars = new ObservableCollection<StarVM>(from sys in _galaxy.Stars
                                                  select new StarVM(sys));
    }

    public string Name
    {
        get { return _galaxy.Name; }
    }
    public ObservableCollection<StarVM> Stars
    {
        get { return _stars; }
    }
}

public class StarVM : ViewModelBase
{
    private Star _star;
    public StarVM(Star star)
    {
        _star = star;
    }
    public string Name
    {
        get { return _star.Name; }
    }
}

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

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

发布评论

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

评论(1

隐诗 2024-08-25 21:18:20

嗯,有脱钩,也有脱钩。

模型对其视图的实现细节一无所知是一回事。那挺好的。

拥有一个不能在动态视图中使用的模型是另一回事。如果模型类没有实现更改通知,则很难可靠地使 UI 与模型状态保持同步。您可以尝试通过将所有更改通知放入视图类中来伪造更改通知,但最终会在某个地方有代码直接更改模型的状态,如果它没有实现更改通知,则视图不会知道这一点,用户界面也会变得不同步。

我可能不会在 Galaxy 中使用公共设置器实现 IList 属性。我会将 Stars 属性设置为 StarList 类型,并创建一个实现 IListStarList 类,除非我有充分的理由不这样做。

Well, there's decoupling and there's decoupling.

It's one thing to have a model that doesn't know anything about the implementation details of its views. That's good.

It's another thing to have a model that can't be used in dynamic views. If a model class doesn't implement change notification, it's going to be difficult to reliably keep the UI in sync with the state of the model. You can try and phony up change notification by putting it all into your view classes, but at the end of the day there's going to be code somewhere that changes the state of the model directly, and if it doesn't implement change notification the views aren't going to know about it and the UI will get out of sync.

I probably wouldn't implement an IList<Star> property with a public setter in Galaxy. I'd make the Stars property of type StarList, and create a StarList class that implemented IList<Star>, unless I had a very good reason not to.

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