在MVVM世界中更改CollectionViewSource源 [英] Changing CollectionViewSource Source in a MVVM world

查看:104
本文介绍了在MVVM世界中更改CollectionViewSource源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个新的VS2010 WPF应用程序,其中只有3个文件MainWindow.xaml,MainWindow.xaml.cs和MainWindowViewModel.cs(在下面列出).如果有人真的有帮助,您可以在几秒钟内重现问题(复制/粘贴).当您运行应用程序时,DataGrid将显示字符串"OldCollection",这是错误的.如果将ItemsSource绑定更改为MyCollection,则会显示正确的"NewCollection".

Edited: I created a new VS2010 WPF appilication with just 3 files MainWindow.xaml, MainWindow.xaml.cs, and MainWindowViewModel.cs (Listed Below). If someone feels really helpful you can recreate the problem in seconds (copy/paste). When you run the app the DataGrid will display string "OldCollection" which is wrong. If you change the ItemsSource binding to MyCollection it displays "NewCollection" which is correct.

完整说明: 最初,我有一个DataGrid,其ItemsSource绑定到MyCollection.我/需要一个方法UpdateCollection,该方法将一个新的ObservableCollection<>分配给MyCollection.通过向MyCollection添加NotifyPropertyChange,UI更新.

Full Description: At first I had a DataGrid with its ItemsSource bound to MyCollection. I have/need a method UpdateCollection that assigns a new ObservableCollection<> to MyCollection. With the addition of NotifyPropertyChange to MyCollection the UI updates.

接下来,有必要引入CollectionViewSource来启用分组.通过将UI绑定到MyCollectionView,对UpdateCollection的调用现在无效.调试器确认MyCollectionView始终包含初始MyCollection.如何使NewCollection反映在视图中?我尝试过View.Refresh(),Binding CollectionViewSource和其他无数策略.

Next it became necessary to introduce a CollectionViewSource to enable grouping. With the UI bound to MyCollectionView, calls to UpdateCollection now have no effect. The debugger confirms that MyCollectionView always contains the initial MyCollection. How can I get my NewCollection to be reflected in the View? I have tried View.Refresh(), Binding CollectionViewSource, and countless other strategies.

注意:主要是其他人关注的是对Collection项目的更改,这些更改不会在不调用Refresh的情况下更新视图(分组/排序).我的问题是我正在向CollectionViewSource分配一个全新的集合,而视图/UI永远不会改变.

Note: Primarily others are concerned with the changes to Collection items not updating the view (grouping/sorting) without calling Refresh. My problem is I am assigning a brand new collection to CollectionViewSource and the view/UI never changes.

// MainWindow.xaml
<Window x:Class="CollectionView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid Name="grid" ItemsSource="{Binding MyCollectionView}" />
    </Grid>
</Window>

//MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace CollectionView
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
    }
}

//MainWindowViewModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.ComponentModel;

namespace CollectionView
{
    class MainWindowViewModel : INotifyPropertyChanged
    {
        public MainWindowViewModel()
        {
            MyCollection = new ObservableCollection<MyObject>() { new MyObject() { TestString = "OldCollection" } };

            MyCollectionViewSource = new CollectionViewSource();

            // Bind CollectionViewSource.Source to MyCollection
            Binding MyBind = new Binding() { Source = MyCollection };
            BindingOperations.SetBinding(MyCollectionViewSource, CollectionViewSource.SourceProperty, MyBind);

            // The DataGrid is bound to this ICollectionView
            MyCollectionView = MyCollectionViewSource.View;

            // This assignment here to demonstrate that View/UI does not update to show "NewCollection"
            MyCollection = new ObservableCollection<MyObject>() { new MyObject() { TestString = "NewCollection" } };
        }

        // Collection Property
        // NotifyPropertyChanged added specifically to notify of MyCollection re-assignment
        ObservableCollection<MyObject> _MyCollection;
        public ObservableCollection<MyObject> MyCollection
        {
            get { return _MyCollection; }
            set
            {
                if (value != _MyCollection)
                {
                    _MyCollection = value;
                    NotifyPropertyChanged("MyCollection");
                }
            }
        }

        public CollectionViewSource MyCollectionViewSource { get; private set; }
        public ICollectionView MyCollectionView { get; private set; }

        // Method updates MyCollection itself (Called via ICommand from another ViewModel)
        public void UpdateCollection(ObservableCollection<MyObject> NewCollection)
        {
            MyCollection = NewCollection;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

    class MyObject
    {
        public string TestString { get; set; }
    }
}

谢谢

推荐答案

我将选择以下两种解决方案之一.

I would choose one of the two following solutions.

首先,您可以使用您的ObservableCollection并创建一次ICollectionView(分组,排序).您可以使用.Clear()并添加新集合中的项目,而不是替换ObservableCollection.这还有不破坏您的分组和排序的额外好处.

First, you could take your ObservableCollection and create an ICollectionView (grouping, sorting) once. Instead of replacing the ObservableCollection you can use .Clear() and add the items from the new Collection. This has the additional bonus of not breaking your grouping and sorting.

第二种方法:每当替换ObservableCollection时,都必须创建一个新的ICollectionView进行排序和分组.

Second approach: whenever you replace your ObservableCollection you have to create a new ICollectionView for sorting and grouping.

 this._view = (ICollectionView)CollectionViewSource.GetDefaultView(this.MyCollection);

如果您使用DefaultView,则可以简单地绑定到您的收藏集

You can simply bind to your collection if you take the DefaultView

 <DataGrid Name="grid" ItemsSource="{Binding MyCollection}" />

,您可以丢弃您的CollectionViewSource代码绑定内容.

and you can throw away your CollectionViewSource code binding stuff.

这篇关于在MVVM世界中更改CollectionViewSource源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆