这是一个延续这个问题 https://stackoverflow.com/questions/34661767/binding-properties-width-sorting-of-datagrid-on-dynamic-tabpage.
1. Setup
我有一个 wpf 窗口,其中包含TabControl
具有动态创建的项目。这ItemSource
这个的TabControl
绑定到一个列表Group
s。这些组包含显示在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>
这一切都很好。
2. 问题
The DataGrid
allows 多列开箱即用。但不幸的是,如果我在标签页之间切换,排序就会丢失。
我想要的是为每个选项卡页/数据网格维护多列排序.
可以绑定SortDirection
of DataGridTextColumn
到一个属性,但不记得排序的列。调试发现,当我切换标签页时,SortDirection
已重置before新的ItemSource
已设置,所以我无法存储它。
问题是:如何保留每个选项卡页/数据网格的多列排序设置?
看了很多文章几乎解决了我的问题,我终于找到了解决方案。
我继承了我自己的类DataGrid
并存储了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
s 并按正确的顺序重置它们。
棘手的部分是找到正确的DataGridColumn
设置其SortDirection
。这是绘制三角形装饰所必需的。我在这里依赖于平等SortMemberPath
and PropertyName
。最终可能需要一种更通用的方法。
在 XAML 中我替换了DataGrid
和我的SortKeepingDataGrid
现在排序是按标签页存储的。
由于我找不到任何其他解决方案,也许这对其他人也有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)