【问题标题】:Best Practice for Binding ItemsControl in MVVM在 MVVM 中绑定 ItemsControl 的最佳实践
【发布时间】:2015-11-02 22:18:11
【问题描述】:

在使用 MVVM 模式时,将项目列表绑定到 ItemsControl 的最佳做法是什么?

1。绑定 ViewModel 列表

从数据库加载项目,创建模型和所有视图模型,然后将视图模型列表绑定到 ItemsControl.ItemsSource:

public class MyMainViewModel
{
    public List<PersonViewModel> Persons { get; set; }
}

2。绑定模型列表

从数据库加载项目,创建模型,然后将这些模型的列表直接绑定到 ItemsControl.ItemsSource:

public class MyMainViewModel
{
    public List<Person> Persons { get; set; }
}

【问题讨论】:

标签: c# wpf mvvm


【解决方案1】:

我认为这里的答案真的是这取决于

首先,您需要评估您的视图是否需要与您的模型进行交互,以便将视图模型包裹特定型号。我们来看一个例子:

public class WebsiteModel
{
    public string URL { get; set; }
}

这里我有一个非常简单的模型,它代表一个网站,没什么花哨的。我可以创建一个包含所有网站的视图模型,例如一对多关系:

public class WebsitesViewModel
{
    //A list of websites.
    public List<WebsiteModel> Websites { get; set; }

    //The command I will use to navigate, where the object parameter will be the WebsiteModel.
    public ICommand NavigateCommand { get; set; }

    ...

    public void Navigate(WebsiteModel model)
    {  
       ...
}

在这里,我希望我的视图能够使用浏览器导航到 URL。我的视图模型包含一个模型列表,我的命令负责导航。

我可以创建一个视图模型来表示单个模型的下一个方法,我会说这是一种 SOLID 方法:

public class WebsiteViewModel
{
    //The website model
    public WebsiteModel Website { get; set; }

    //The command I will use to navigate, no parameters needed.
    public ICommand NavigateCommand { get; set; }

    ...

    public void Navigate()
    {  
       ...
}

在这种情况下,我需要另一个视图模型,它将WebsiteViewModel 列表公开给我的视图。

public List<WebsiteViewModel> Websites { get; set; }

事实上并没有真正的最佳实践。两种方法都没有真正胜过另一种方法。每种方法都有好处,但是选择的方法实际上取决于实现。在这种情况下,我会说方法 2 过于复杂。然而,视图模型很快变得非常大的情况并不少见,分离关注点的需要将迫使您创建更小的类,甚至视图模型将您的模型包装在其中,使方法 2 成为可行的选择。

所以总结一下。这两种方法都不是最佳实践

【讨论】:

    【解决方案2】:

    唯一“正确”的方法是一直使用 ViewModel。

    虽然最初的工作量更大,但它为您提供了更大的灵活性,并在以后减少了错误。

    不要获取,当你的模型应该只在它的有界上下文中有效并且当你将你的 ViewModel 绑定到视图时,你有一个泄漏的抽象。视图会意识到模型,并且模型的每次更改都会影响您的视图。

    此外,重构在 XAML 中不起作用。因此,如果您通过重构命名模型属性,您的 XAML 仍将绑定到旧属性。这不会给您带来编译错误,并且您的有界元素将保持为空(在最好的情况下)或崩溃(在最坏的情况下)。

    这可能很难弄清楚和解决。正如 Scroog1 评论的那样,它引入了内存泄漏。在小型应用程序中可能不明显,但在处理大数据集的应用程序中可能会导致内存不足异常。

    在允许的情况下,您应该使用自动映射库从 Model 映射到 ViewModel,这将减少一些样板代码。但请记住避免 ViewModel 到 Model 的自动映射,因为不鼓励这样做。

    您希望避免模型中的更改影响不同有界上下文中的代码,即您不希望在休息服务中公开每个数据库或模型更改,即使更改不会影响给定的休息操作.

    同样的策略可以应用于 n 层模型(View、ViewModel、(域)模型层、Services 和 Infrastructure)

    【讨论】:

      【解决方案3】:

      我认为没有正确的方法,使用模型是务实和简单的方法,使用视图模型更耗时但更解耦......

      你应该看看这篇文章: http://blog.alner.net/archive/2010/02/09/mvvm-to-wrap-or-not-to-wrap.aspx

      还有:http://www.codeproject.com/Articles/61147/MVVM-Creating-ViewModel-Wrap-your-business-object

      【讨论】:

        猜你喜欢
        • 2018-11-03
        • 1970-01-01
        • 2015-12-14
        • 1970-01-01
        • 2019-04-26
        • 2012-08-19
        • 2017-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多