I am sorting a datagrid within a UserControl that is displayed inside of a TabControl.
The main window contains the TabControl as shown here.
<Grid>
<TabControl x:Name="EquipTabs" ItemsSource="{Binding Equipment}" >
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ctrls:MachData DataContext="{Binding Path=MachineViewModel}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
The user control sorts the datagrid correctly when the first tab is activated. However, when I click on a different tab or switch back to the original one, the datagrid doesn't sort.
<UserControl.Resources>
<CollectionViewSource x:Key="StatesSource" Source="{Binding States}" >
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="StartTime" Direction="Descending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<Grid>
<DataGrid x:Name="dgStates" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
ItemsSource="{Binding Source={StaticResource StatesSource}}">
</DataGrid>
</Grid>
The trace for the binding shows the following:
Deactivate
Replace item at level 0 with {NullDataItem}
Activate with root item MachDataViewModel (hash=25379957)
At level 0 using cached accessor for MachDataViewModel.States: RuntimePropertyInfo(States)
Why does the sort only occur initially?
Thanks for any help.
This happens because of the way DataGrid
works. DataGrid
clears SortDescriptions
before setting ItemsSource
.
If we can apply our SortDescriptions
after DataGrid
is finished with ItemsSource
, our SortDescriptions
will work.
TargetUpdated
event comes to rescue, but to use it we have to set NotifyOnTargetUpdated=True
in our Binding
.
<DataGrid
TargetUpdated="dgStates_TargetUpdated"
ItemsSource="{Binding Source={StaticResource StatesSource}, NotifyOnTargetUpdated=True}" />
Code :
private void dgStates_TargetUpdated(object sender, DataTransferEventArgs e)
{
CollectionViewSource sc = this.Resources["StatesSource"] as CollectionViewSource;
sc.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", System.ComponentModel.ListSortDirection.Ascending));
}