【问题标题】:CollectionViewSource Violates MVVMCollectionViewSource 违反 MVVM
【发布时间】:2014-07-31 06:52:31
【问题描述】:

我有一个 MVVM 应用程序,在我的几个虚拟机中,我使用CollectionViewSource.GetDefaultView(datasource) 来初始化我的 ICollectionView,它运行良好。 我担心在我的虚拟机中使用 CVS 时是否违反了 MVVM?

感谢大家的意见

【问题讨论】:

  • 仅供参考,我的工作需要过滤和搜索,而我在 VM 中拥有 CVS 的方式对我来说更容易、更高效,除非有更简单、更有效的方法。
  • 不时“违反 MVVM”具体有什么问题?代码很难写吗?难以阅读?很难测试?很难改变?模式是指导,而不是法律。
  • 如果我有机会或方法让某些东西看起来或工作得更好,我会毫不犹豫地改变它吗?
  • 为什么不使用 LinQ 在视图模型中过滤您的集合?

标签: c# .net wpf mvvm


【解决方案1】:

我通常更喜欢在视图模型中公开集合并在 XAML 中创建集合视图源:

<Window.Resources>
    <CollectionViewSource x:Key="CollectionViewSource" Source="{Binding Items}">
        <i:Interaction.Behaviors>
            <behaviors:MyFilterLogic />
        </i:Interaction.Behaviors>
    </CollectionViewSource>
</Window.Resources>

<ItemsControl ItemsSource="{Binding Source={StaticResource CollectionViewSource}}" />

以及行为类:

public class MyFilterLogic: Behavior<CollectionViewSource>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.Filter += AssociatedObjectOnFilter;
    }

    private void AssociatedObjectOnFilter(object sender, FilterEventArgs filterEventArgs)
    {
        // filter logic
    }
}

其他一些专家实际上并不介意在他们的视图模型中公开 CollectionView: https://stackoverflow.com/a/979943/3351315

【讨论】:

  • 您不能使用此方法使用过滤器。
  • 我的情况需要过滤和搜索
  • 当然可以 - 您可以将自定义行为逻辑附加到 CollectionViewSource 对象。我修改了答案以显示过滤。
  • 我将实现留在了虚拟机中。当我有时间时,我会回去用你的方法改变一些事情。我会给你一点,但我的 SOF 声誉还不够高。谢谢@eshaham
  • 没关系,我很高兴能帮上忙
【解决方案2】:

看看这个问题的答案:Trigger Filter on CollectionViewSource

它展示了一种通过将传统项目包装在 ViewModel 中来添加 CollectionSourceView 的 MVVM 方式。

据我所知,这种方式并没有违反 MVVM,并且仍然可以使用漂亮的分组、过滤和排序功能。

不要因为您没有像大多数示例那样在 Xaml 中使用 CollectionViewSources 而感到难过;事实上,在代码中,在 ViewModel 中使用它们我感觉好多了。

为了操作过滤、分组和排序,我将命令添加到 ViewModel 并在执行时更改 ICollectionView

【讨论】:

  • 这就是我在我的虚拟机中所拥有的
  • 那你怎么担心。据我所知,它并没有违反 MVVM
  • 事实上,CVS 位于 System.Windows.Data 命名空间中
  • @asdbabil 视图模型是专门为应用程序编写的。您不太可能在 wpf、silverlight 和/或 windows phone 7 中使用相同的视图模型。MVVM 的想法是帮助您强制执行关注点分离。它不是帮助您设计可重用组件的模式。尽量不要因为将视图模型程序集与 WPF 耦合而感到难过,相反,请担心将视图模型类与呈现它们的视图分离。
  • CVS 在 Data 命名空间中的事实完全不相关。 MVVM 位于不同的抽象层之上。
【解决方案3】:

可能让你感觉不好的事情:

  • 那个工厂方法,GetDefaultView。由于事物的静态性质,它也让我感到肮脏。
  • 它绑定到 UI 线程,正如您从工作线程更改 ObservableCollection&lt;T&gt; 可能知道的那样。

CollectionViewSource 是一种抽象,它允许您指定您希望如何组织集合,但它不显示集合 - ItemsControl 可以做到这一点。这是很好的 MVVM!

一般来说,我更喜欢将CollectionViewSource 排除在我的视图模型之外,除非我需要过滤器只是因为它使我的视图模型更加复杂。从长远来看,DataTemplateSelectorVisualStateGroup 通常是更改收藏展示的更简单方法。

【讨论】:

  • 我不太关心在 SL 或 Windows phone 7 应用程序中重用我的虚拟机。这更像是我们决定移动文件,假设我们决定将所有 VM 重新定位在类库程序集中,而不是在 wpf 应用程序程序集中。在 VM 中使用 CVS 时,感觉就像在 VM 中实例化一个控件,例如 Combobox 或 Button。然而,在做了一些研究并在这里得到了一些反馈之后,我感觉还不错:)
猜你喜欢
  • 2010-11-01
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 1970-01-01
  • 2015-05-19
相关资源
最近更新 更多