c# – 在MVVM世界中更改CollectionViewSource Source

前端之家收集整理的这篇文章主要介绍了c# – 在MVVM世界中更改CollectionViewSource Source前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
编辑:我创建了一个新的VS2010 WPF应用程序,只有3个文件MainWindow.xaml,MainWindow.xaml.cs和MainWindowviewmodel.cs(下面列出).如果有人觉得非常有帮助,您可以在几秒钟内重新创建问题(复制/粘贴).当您运行应用程序时,DataGrid将显示错误的字符串“OldCollection”.如果将ItemsSource绑定更改为MyCollection,则显示“NewCollection”,这是正确的.

详细描述:
起初我有一个DataGrid,其ItemsSource绑定到MyCollection.我需要一个方法UpdateCollection来分配一个新的ObservableCollection<>到MyCollection.通过向MyCollection添加NotifyPropertyChange,UI更新.@H_404_4@

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

注意:主要是其他人关注收集项目的更改而不更新视图(分组/排序)而不调用Refresh.我的问题是我正在为CollectionViewSource分配一个全新的集合,并且视图/ UI永远不会改变.@H_404_4@

// 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; }
    }
}

谢谢,@H_404_4@

解决方法

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

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

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

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

如果使用DefaultView,只需绑定到您的集合即可@H_404_4@

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

你可以扔掉你的CollectionViewSource代码绑定的东西.@H_404_4@

猜你在找的C#相关文章