在MVVM中绑定ItemsControl的最佳实践

时间:2015-11-02 22:18:11

标签: c# wpf mvvm

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

1。绑定ViewModel列表

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

Installing collected packages: six, sqlparse, decorator, Tempita, sqlalchemy-migrate, IMDbPY
  Found existing installation: six 1.4.1
    DEPRECATION: Uninstalling a distutils installed project (six) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.
    Uninstalling six-1.4.1:
Exception:
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/pip/basecommand.py", line 211, in main
    status = self.run(options, args)
  File "/Library/Python/2.7/site-packages/pip/commands/install.py", line 311, in run
    root=options.root_path,
  File "/Library/Python/2.7/site-packages/pip/req/req_set.py", line 640, in install
    requirement.uninstall(auto_confirm=True)
  File "/Library/Python/2.7/site-packages/pip/req/req_install.py", line 716, in uninstall
    paths_to_remove.remove(auto_confirm)
  File "/Library/Python/2.7/site-packages/pip/req/req_uninstall.py", line 125, in remove
    renames(path, new_path)
  File "/Library/Python/2.7/site-packages/pip/utils/__init__.py", line 315, in renames
    shutil.move(old, new)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 302, in move
    copy2(src, real_dst)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 131, in copy2
    copystat(src, dst)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 103, in copystat
    os.chflags(dst, st.st_flags)
OSError: [Errno 1] Operation not permitted: '/tmp/pip-QNP1Pr-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/six-1.4.1-py2.7.egg-info'

2。绑定模型列表

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

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

3 个答案:

答案 0 :(得分:1)

我认为这里的答案实际上是取决于

首先,您需要评估您的视图是否需要与您的模型进行交互,以便视图模型能够包裹 a特殊模型。让我们看一个例子:

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)
    {  
       ...
}

我希望我的观点能够使用浏览器导航到网址。我的视图模型包含模型列表,我的命令负责导航。

下一个方法我可以创建一个视图模型来表示单个模型,我想这是一个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成为可行的选择。

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

答案 1 :(得分:0)

唯一正确的&#34;这样做的方法是一直使用ViewModels。

虽然最初工作量很大,但它会为您提供更大的灵活性和更少的错误。

不要得到,当你的模型应该只在它的有限上下文中有效时,当你将ViewModel绑定到视图时,你会有一个漏洞的抽象。 View会发现模型以及模型的每次更改都会影响您的View。

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

这很难弄清楚。同样在Scroog1评论时,它引入了内存泄漏。在小型应用程序中可能并不明显,但使用大数据集的应用程序可能会导致内存不足。

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

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

相同的策略可应用于n层模型(View,ViewModel,(Domain)Model层,服务和基础架构)

答案 2 :(得分:-1)

我认为没有正确的方法,使用模型是务实且简单的方法,使用视图模型更耗时但更加分离......

你应该看一下这篇文章: 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