gpt4 book ai didi

c# - 如何在 DataGrid 和 CollectionViewSource 之间同步排序标记?

转载 作者:太空宇宙 更新时间:2023-11-03 13:58:11 25 4
gpt4 key购买 nike

您如何实现(最好是纯粹在 XAML 中)WPF DataGrid 的列标题中的排序标记与 CollectionViewSource 中的当前排序顺序同步?

例如,我有以下示例代码,它显示了 C:\中所有文件的属性,按长度排序:

<Window x:Class="DataGridSortTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<CollectionViewSource x:Key="items" Source="{Binding Files}">
<CollectionViewSource.SortDescriptions>
<cm:SortDescription PropertyName="Length"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<DataGrid ItemsSource="{Binding Source={StaticResource items}}"/>
</Grid>
</Window>

MainWindow.xaml.cs 中的代码隐藏是:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

Files = Directory.GetFiles(@"C:\").Select(f => new FileInfo(f)).ToList();

DataContext = this;
}

public IEnumerable<FileInfo> Files { get; private set; }
}

当我启动这个程序时,它看起来像这样:

Screenshot

即文件排序正确,但标题中的标记丢失。对于“标记”,我的意思是:

Sort marker

注意:我正在寻找一个通用解决方案。仅设置 DataGridColumn.SortDirection 不是解决方案。我正在寻找一种方法来指示 DataGrid 自动从 Collection View 中检索排序顺序。

最佳答案

这似乎是个老问题,但今天我遇到了同样的问题,并找到了一个通用的解决方案。因此,想法是 SortDescriptions 集合隐式实现 INotifyCollectionChanged,因此我们有能力观察它并适本地设置 DataGrid“排序标记”。我在单独的行为中实现了这个:

public class DataGridSortDescriptionsSyncBehavior : Behavior<DataGrid>
{
protected override void OnAttached()
{
base.OnAttached();

var view = CollectionViewSource.GetDefaultView(AssociatedObject.ItemsSource);
var notifyCollection = view.SortDescriptions as INotifyCollectionChanged;
if (notifyCollection != null)
notifyCollection.CollectionChanged += SortDescriptions_CollectionChanged;
}

protected override void OnDetaching()
{
base.OnDetaching();

var view = CollectionViewSource.GetDefaultView(AssociatedObject.ItemsSource);
var notifyCollection = view.SortDescriptions as INotifyCollectionChanged;
if (notifyCollection != null)
notifyCollection.CollectionChanged -= SortDescriptions_CollectionChanged;
}

private void SortDescriptions_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Reset)
{
// clear all columns sort directions
foreach (var column in AssociatedObject.Columns)
column.SortDirection = null;
}

if (e.NewItems != null)
{
// set columns sort directions
foreach (SortDescription descr in e.NewItems)
SetSortDirection(descr.PropertyName, descr.Direction);
}

if (e.OldItems != null)
{
// reset columns sort directions
foreach (SortDescription descr in e.OldItems)
SetSortDirection(descr.PropertyName, null);
}
}

private void SetSortDirection(string sortMemberPath, ListSortDirection? direction)
{
var column = AssociatedObject.Columns.FirstOrDefault(c => c.SortMemberPath == sortMemberPath);
if (column != null)
{
column.SortDirection = direction;
}
}
}

对于那些不了解行为的人 - 您需要添加对 System.Windows.Interactivity 程序集的引用并将行为应用于 DataGrid:

<DataGrid ItemsSource="{Binding Data}">
<i:Interaction.Behaviors>
<local:DataGridSortDescriptionsSyncBehavior />
</i:Interaction.Behaviors>
</DataGrid>

现在,当您修改收藏时,“排序标记”会自动调整。另外请注意,此行为仅适用于默认 Collection View 。如果您正在使用您明确创建的 Collection View - 只需将其发送到行为(例如,通过行为的属性)并使用它而不是默认 Collection View 。

关于c# - 如何在 DataGrid 和 CollectionViewSource 之间同步排序标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11500666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com