编辑:我创建了一个新的VS2010
WPF应用程序,只有3个文件MainWindow.xaml,MainWindow.xaml.cs和MainWindowviewmodel.cs(下面列出).如果有人觉得非常有帮助,您可以在几秒钟内重新创建问题(复制/粘贴).当您运行应用程序时,DataGrid将显示错误的字符串“OldCollection”.如果将ItemsSource绑定更改为MyCollection,则显示“NewCollection”,这是正确的.
详细描述:
起初我有一个DataGrid,其ItemsSource绑定到MyCollection.我需要一个方法UpdateCollection来分配一个新的ObservableCollection<>到MyCollection.通过向MyCollection添加NotifyPropertyChange,UI更新.
接下来,有必要引入一个CollectionViewSource来启用分组.将UI绑定到MyCollectionView后,对UpdateCollection的调用现在无效.调试器确认MyCollectionView始终包含初始MyCollection.如何让我的NewCollection反映在View中?我尝试过View.Refresh(),绑定CollectionViewSource,以及无数其他策略.
注意:主要是其他人关注收集项目的更改而不更新视图(分组/排序)而不调用Refresh.我的问题是我正在为CollectionViewSource分配一个全新的集合,并且视图/ UI永远不会改变.
// 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; } } }
谢谢,
解决方法
我会选择以下两种解决方案之一.
首先,您可以使用ObservableCollection并创建一次ICollectionView(分组,排序).您可以使用.Clear()并添加新Collection中的项目,而不是替换ObservableCollection.这还有一个额外的好处,就是不会破坏你的分组和排序.
第二种方法:无论何时替换ObservableCollection,都必须创建一个新的ICollectionView进行排序和分组.
this._view = (ICollectionView)CollectionViewSource.GetDefaultView(this.MyCollection);
如果使用DefaultView,只需绑定到您的集合即可
<DataGrid Name="grid" ItemsSource="{Binding MyCollection}" />
你可以扔掉你的CollectionViewSource代码绑定的东西.