CollectionViewSource 不会在属性更改时重新排序

swift

1个回答

写回答

林二木

2025-06-13 20:55

+ 关注

AI
AI

CollectionViewSource 是 WPF 中一个非常有用的类,它提供了对数据集合进行排序、分组和筛选的功能。然而,有时我们可能遇到一个问题,就是当数据集合的属性发生更改时,CollectionViewSource 并不会自动重新排序。本文将介绍这个问题,并提供一种解决方案。

在 WPF 中,我们经常使用 CollectionViewSource 来对数据进行排序和分组。它是一个非常方便的工具,可以帮助我们管理和呈现大量的数据。然而,有时候我们希望在数据集合的属性更改后自动重新排序,以便及时更新界面。但是,默认情况下,CollectionViewSource 并不会提供这个功能。

为了解决这个问题,我们需要自定义一个类,继承自 CollectionViewSource,并重写其 Refresh() 方法。在 Refresh() 方法中,我们可以手动对数据集合进行排序,以确保界面上的数据始终是最新的。

下面是一个示例代码,演示了如何自定义一个带有自动排序功能的 CollectionViewSource 类:

csharp

public class AutoSortingCollectionViewSource : CollectionViewSource

{

protected override void Refresh()

{

// 获取数据集合

var items = SourceCollection.Cast<object>().ToList();

// 根据属性进行排序

items = items.OrderBy(item => ((YourItemType)item).YourProperty).ToList();

// 创建新的 CollectionView

var view = new ListCollectionView(items);

// 设置新的 CollectionView 作为数据源

View = view;

}

}

在上面的代码中,我们重写了 CollectionViewSource 的 Refresh() 方法,首先获取数据集合,然后根据需要进行排序,最后将排序后的结果设置为新的 CollectionView。这样,当数据集合的属性发生更改时,我们只需要手动调用 Refresh() 方法,就可以实现自动重新排序的功能。

案例代码

假设我们有一个名为 Person 的类,它有两个属性:Name 和 Age。我们希望根据 Age 属性对 Person 对象进行排序。下面是一个简单的示例代码:

csharp

public class Person

{

public string Name { get; set; }

public int Age { get; set; }

}

public class MAInWindowViewModel : INotifyPropertyChanged

{

private ObservableCollection<Person> _people;

private AutoSortingCollectionViewSource _collectionViewSource;

public ObservableCollection<Person> People

{

get { return _people; }

set

{

_people = value;

OnPropertyChanged(nameof(People));

// 在属性更改后手动调用 Refresh() 方法

_collectionViewSource.Refresh();

}

}

public ICollectionView PeopleView

{

get { return _collectionViewSource.View; }

}

public MAInWindowViewModel()

{

_people = new ObservableCollection<Person>()

{

new Person { Name = "John", Age = 30 },

new Person { Name = "Alice", Age = 25 },

new Person { Name = "Bob", Age = 35 }

};

_collectionViewSource = new AutoSortingCollectionViewSource();

_collectionViewSource.Source = _people;

}

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)

{

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

}

}

在上面的代码中,我们创建了一个名为 MAInWindowViewModel 的 ViewModel 类,其中包含一个名为 People 的 ObservableCollection,用于存储 Person 对象。在 People 属性的 setter 方法中,我们手动调用了 Refresh() 方法,以确保数据集合的属性更改后能够自动重新排序。

最后,在 WPF 的 XAML 中,我们可以使用 CollectionViewSource 的 View 属性绑定到我们的数据集合,并在界面上显示排序后的结果。例如:

xaml

<Window.DataContext>

<local:MAInWindowViewModel />

</Window.DataContext>

<Grid>

<ItemsControl ItemsSource="{Binding PeopleView}">

<ItemsControl.ItemTemplate>

<DataTemplate>

<StackPanel Orientation="Horizontal">

<TextBlock Text="{Binding Name}" />

<TextBlock Text="{Binding Age}" Margin="10,0,0,0" />

</StackPanel>

</DataTemplate>

</ItemsControl.ItemTemplate>

</ItemsControl>

</Grid>

在上面的 XAML 中,我们使用 ItemsControl 绑定到 PeopleView 属性,然后使用 DataTemplate 来定义每个 Person 对象的显示方式。这样,当数据集合的属性发生更改时,界面上的数据将自动重新排序。

通过自定义一个继承自 CollectionViewSource 的类,并重写其 Refresh() 方法,我们可以实现在属性更改时自动重新排序的功能。在本文中,我们演示了一个简单的示例代码,并提供了一种解决方案。希望这对你在 WPF 开发中处理数据集合排序问题有所帮助!

举报有用(4分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号