记住WPF DataGrid排序顺序 [英] Remember WPF DataGrid sort order

查看:139
本文介绍了记住WPF DataGrid排序顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是这个问题的延续。

我有一个包含动态创建项目的 TabControl 的wpf窗口。该 TabControl ItemSource 绑定到组列表 s。这些组包含在 TabPage 中的 DataGrid 中显示的元素列表。

I have a wpf window that contains a TabControl with dynamically created items. The ItemSource of this TabControl is binded to a list of Groups. These groups contain a list of elements that is displayed in a DataGrid on the TabPage.

XAML:

<Window x:Name="window" x:Class="TestWpf.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:TestWpf"
    Title="MainWindow" Height="350" Width="525">
    <TabControl x:Name="tabControl" BorderThickness="0" ItemsSource ="{Binding Groups, ElementName=window, NotifyOnSourceUpdated=True}">
        <TabControl.ItemTemplate>
            <DataTemplate DataType="{x:Type vm:Group}">
                <TextBlock Padding="2" Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate x:Name="contentTemplate" DataType="{x:Type vm:Group}">
                <DataGrid x:Name="dgElements" ItemsSource="{Binding Elements, BindsDirectlyToSource=True}" DockPanel.Dock="Top" AutoGenerateColumns="False" >
                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="clmName" Header="Name" Binding="{Binding Name}" IsReadOnly="True" CanUserReorder="False" />
                    <DataGridTextColumn x:Name="clmDesc" Header="Description" Binding="{Binding Description}" IsReadOnly="True" CanUserReorder="False" />
                    </DataGrid.Columns>
                </DataGrid>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Window>

这一切正常。

DataGrid 允许多列开箱即用。但是不幸的是,如果我在标签页之间切换,排序就会丢失。

我希望为每个tabpage / datagrid 维护多列排序。

The DataGrid allows multi-column sort out of the box. But unfortunatly, if I switch between the tabpages, the sorting is lost.
I want that the multi-column sorting is maintained for each tabpage/datagrid.

可以将 SortDirection DataGridTextColumn 绑定到属性,但这不记住列的排序顺序。调试我发现当我切换标签页时, SortDirection 在新的 ItemSource 被设置,所以我不能存储这个。

It is possible to bind the SortDirection of DataGridTextColumn to a property, but that does not remember the sort order of the columns. And debugging I found that when I switch the tabpage, the SortDirection is reset before the new ItemSource is set, so I can't store this.

问题是:如何保持每个tabpage / datagrid的多列排序设置?

推荐答案

阅读了很多文章后,几乎解决了我的问题,我终于找到了一个解决方案。
我从 DataGrid 继承了我自己的类,并存储 SortDescriptions 每个 ItemSource 字典中

After reading a lot of articles only almost solving my problem, I finally found a solution.
I inherited my own class from DataGrid and stored the SortDescriptions per ItemSource in a Dictionary:

public class SortKeepingDataGrid : DataGrid
{
    // Dictionary to keep SortDescriptions per ItemSource
    private readonly Dictionary<object, List<SortDescription>> m_SortDescriptions =
        new Dictionary<object, List<SortDescription>>();

    protected override void OnSorting(DataGridSortingEventArgs eventArgs)
    {
        base.OnSorting(eventArgs);
        UpdateSorting();
    }
    protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
    {
        base.OnItemsSourceChanged(oldValue, newValue);

        ICollectionView view = CollectionViewSource.GetDefaultView(newValue);
        view.SortDescriptions.Clear();

        // reset SortDescriptions for new ItemSource
        if (m_SortDescriptions.ContainsKey(newValue))
            foreach (SortDescription sortDescription in m_SortDescriptions[newValue])
            {
                view.SortDescriptions.Add(sortDescription);

                // I need to tell the column its SortDirection,
                // otherwise it doesn't draw the triangle adornment
                DataGridColumn column = Columns.FirstOrDefault(c => c.SortMemberPath == sortDescription.PropertyName);
                if (column != null)
                    column.SortDirection = sortDescription.Direction;
            }
    }

    // Store SortDescriptions in dictionary
    private void UpdateSorting()
    {       
        ICollectionView view = CollectionViewSource.GetDefaultView(ItemsSource);
        m_SortDescriptions[ItemsSource] = new List<SortDescription>(view.SortDescriptions);
    }
}

所以,基本上每当用户改变排序时,我调用 UpdateSorting 并存储当前 SortDescription s在每个 ItemSource 字典。

ItemSource 已更改时,我查找 SortDescription 以正确的顺序重置它们。

So, basically, whenever the user changes the sorting, I call UpdateSorting and store the current SortDescriptions in the per ItemSource dictionary.
When the ItemSource has changed, I look up the SortDescriptions and reset them in the correct order.

棘手的部分是找到正确的 DataGridColumn 来设置它的 SortDirection 。这是必要的画三角形装饰。我这里依赖于 SortMemberPath PropertyName 的相等性。最终可能需要一种更通用的方法。

The tricky part is finding the correct DataGridColumn to set its SortDirection. This is necessary to draw the triangled adornment. I here rely on the equality of SortMemberPath and PropertyName. Eventually a more generic approach could be necessary.

在XAML中,我将替换为 DataGrid c> SortKeepingDataGrid ,现在每个标签页都存储排序。

In the XAML I replaced the DataGrid with my SortKeepingDataGrid and now the sorting is stored per tabpage.

由于我找不到任何其他解决方案,也许这将帮助别人。

Since I could not find any other solution, maybe this will help others too.

这篇关于记住WPF DataGrid排序顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆