8
votes

I've a UserControl, which basically only contains a DataGrid. In this DataGrid, I've a list of event(Severity - Date - Message). The user controls is bound through the ViewModelLocator of MVVMLight Toolkit.

I've added two things:

In my UserControl resources:

<UserControl.Resources>
    <CollectionViewSource x:Key="SortedEvents" Source="{Binding Events}">
        <CollectionViewSource.SortDescriptions>
            <componentModel:SortDescription PropertyName="EventTime" Direction="Descending"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</UserControl.Resources>

which is used by the DataGrid:

<DataGrid ItemsSource="{Binding Source={StaticResource SortedEvents}}" AutoGenerateColumns="False" >

I also have the SortedDirection set on the DataGridTextColumn.SortDirection:

<DataGridTextColumn Binding="{Binding EventTime}"  Header="Time" IsReadOnly="True" SortDirection="Descending"/>

When I check the designer, I see the small arrow showing that the DataGrid is sorted correctly.

But when I launch the application, the list is not sorted, the arrow is not here. If I click on the column to sort it, it sorts everything correctly, its just the default value which doesn't seems to work.

What am I missing? (This dataGrid/column are not even named, so I cannot try to edit them through something else).

(Initially I was only having the SortDirectionon the DataGridTextColumn. Same result)

2

2 Answers

2
votes

About the "small arrow" check here: ColumnHeader arrows not reflected when sorting a DataGrid in XAML

And for a more complex answer: Pre-sorting a DataGrid in WPF

I think main part is:

NOTE: the "scm" namespace prefix maps to System.ComponentModel where the SortDescription class lives.

xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"

Edit

DataGrid removes the SortDescriptions and GroupDescriptions whenever its ItemsSource changes. This is necessary because unlike other ItemsControls, DataGrid itself adds SortDescriptions when the user clicks the column header and leaving them as is may crash if they are not compatible with the new ItemsSource.

protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
    {
        if (SetupSortDescriptions != null && (newValue != null)) 
            SetupSortDescriptions(this, new ValueEventArgs<CollectionView>((CollectionView)newValue)); 

        base.OnItemsSourceChanged(oldValue, newValue);
    }
0
votes

It seems that you just needed to add IsLiveSortingRequested="True" to your CollectionViewSource.

 <UserControl.Resources>
    <CollectionViewSource x:Key="SortedEvents" Source="{Binding Events}" IsLiveSortingRequested="True">
        <CollectionViewSource.SortDescriptions>
            <componentModel:SortDescription PropertyName="EventTime" Direction="Descending"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</UserControl.Resources>

That worked for me