记住WPF DataGrid排序顺序 [英] Remember WPF DataGrid sort order
问题描述
这是这个问题的延续。
我有一个包含动态创建项目的 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 Group
s. 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 SortDescription
s in the per ItemSource
dictionary.
When the ItemSource
has changed, I look up the SortDescription
s 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屋!