加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 08:10:41 所属栏目:百科 来源:网络整理
导读:编辑:我创建了一个新的VS2010 WPF应用程序,只有3个文件MainWindow.xaml,MainWindow.xaml.cs和MainWindowViewModel.cs(下面列出).如果有人觉得非常有帮助,您可以在几秒钟内重新创建问题(复制/粘贴).当您运行应用程序时,DataGrid将显示错误的字符串“OldColle
编辑:我创建了一个新的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代码绑定的东西.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读