How can I get the CollectionView that is defined in XAML

c#, code-behind, collectionviewsource, wpf, xaml

Solution

Found a way, based on J. Lennon's answer. If I pass something that has access to the resources with my command, then I can look up the `CollectionViewSource` there.

In XAML (`CollectionViewResource` as above):

<Button Command="{Binding Command}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">Do it!</Button>

And in the VM code:

private void Execute(object parm)
{
    var fe = (FrameworkElement)parm;
    var cvs = (CollectionViewSource)fe.FindResource("cvs");
    cvs.View.Refresh();
}

The `Execute` is the one that is given to the RelayCommand.

This would answer the question, but I don't like it very much. Opinions?

Problem

I wanted to bind to an `ObservableCollection` in XAML and also apply the grouping there. In principle, this worked fine. ``` <UserControl.Resources> <CollectionViewSource x:Key="cvs" Source="{Binding Path=TestTemplates}"> <CollectionViewSource.SortDescriptions> <scm:SortDescription PropertyName="Title"/> </CollectionViewSource.SortDescriptions> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="TestCategory"/> </CollectionViewSource.GroupDescriptions> </CollectionViewSource> </UserControl.Resources> ``` Then the data binding expression became `ItemsSource="{Binding Source={StaticResource ResourceKey=cvs}}"` instead of `ItemsSource="{Binding Path=TestTemplates}"`. At first, everything seemed cool, until I wanted to refresh the UI from the view model. The problem is, that `CollectionViewSource.GetDefaultView(TestTemplates)` returned a different view than the one from XAML where the grouping was applied. Thus, I could not set selection or do anything useful with it. I could fix it by binding the list again directly to the view model's property and setting up the grouping in the code-behind. But I'm not that happy with this solution. ``` private void UserControlLoaded(object sender, RoutedEventArgs e) { IEnumerable source = TemplateList.ItemsSource; var cvs = (CollectionView)CollectionViewSource.GetDefaultView(source); if (cvs != null) { cvs.SortDescriptions.Add(new SortDescription("Title", ListSortDirection.Ascending)); cvs.GroupDescriptions.Add(new PropertyGroupDescription("TestCategory")); } } ``` I assume, the reason for that is already given by John Skeet here. Nevertheless, I would expect that there should be a way to get the right view. Am I wrong?

Original source

Related problems