Ответ 1
Отличный вопрос и интересное наблюдение. При ближайшем рассмотрении выясняется, что DataGrid очищает описания сортировки предыдущего элемента ItemsSource до того, как будет установлен новый. Вот его код для OnCoerceItemsSourceProperty:
private static object OnCoerceItemsSourceProperty(DependencyObject d, object baseValue)
{
DataGrid grid = (DataGrid) d;
if ((baseValue != grid._cachedItemsSource) && (grid._cachedItemsSource != null))
{
grid.ClearSortDescriptionsOnItemsSourceChange();
}
return baseValue;
}
Такое поведение наблюдается только в DataGrid. Если вы использовали ListBox вместо этого (чтобы отобразить коллекцию "Игроки" выше), поведение будет отличаться, и SortDescriptions все равно останется после выбора разных элементов из родительского datagrid.
Итак, я предполагаю, что решение этого заключается в том, чтобы каким-то образом повторно применять описания сортировки коллекции игроков всякий раз, когда изменяется выбранный элемент в родительском DataGrid (то есть "lstLevel" ).
Однако я не уверен на 100% об этом и, вероятно, нуждаюсь в большем количестве тестирования/расследования. Надеюсь, что я смог что-то внести. =)
EDIT:
В качестве предлагаемого решения вы можете поместить обработчик для lstLevel.SelectionChanged в свой конструктор, прежде чем устанавливать свойство lstLevel.ItemsSource. Что-то вроде этого:
lstLevel.SelectionChanged +=
(sender, e) =>
{
levels.ToList().ForEach((p) =>
{
CollectionViewSource.GetDefaultView(p.Players)
.SortDescriptions
.Add(new SortDescription("Name", ListSortDirection.Ascending));
});
};
lstLevel.ItemsSource = levels;
EDIT2:
В ответ на проблемы, с которыми вы сталкиваетесь в отношении навигации по клавиатуре, я предлагаю вместо обработки события "CurrentChanged" обрабатывать событие lstLevel.SelectionChanged. Я размещаю необходимые обновления, которые вам нужно сделать ниже. Просто скопируйте пасту в свой код и посмотрите, хорошо ли это работает.
XAML:
<!-- Players data, with sort on the Name column -->
<StackPanel Grid.Column="1">
<Label>DataGrid:</Label>
<DataGrid Name="lstPlayers" AutoGenerateColumns="False"
CanUserSortColumns="False"
ItemsSource="{Binding ElementName=lstLevel, Path=SelectedItem.Players}">
<DataGrid.Columns>
<DataGridTextColumn Header="Name"
Binding="{Binding Path=Name, Mode=TwoWay}"
Width="*" />
<DataGridTextColumn Header="Age"
Binding="{Binding Path=Age, Mode=TwoWay}"
Width="80">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
<StackPanel Grid.Column="2">
<Label>ListBox:</Label>
<ListBox ItemsSource="{Binding ElementName=lstLevel, Path=SelectedItem.Players}" DisplayMemberPath="Name" />
</StackPanel>
Code-behind (конструктор):
lstLevel.SelectionChanged +=
(sender, e) =>
{
levels.ToList().ForEach((p) =>
{
CollectionViewSource.GetDefaultView(p.Players)
.SortDescriptions
.Add(new SortDescription("Name", ListSortDirection.Ascending));
});
};
lstLevel.ItemsSource = levels;