sorting a bound ItemsControl in a DataTemplate (XAML only)
Asked Answered
C

2

10

Is there a XAML only way to automatically sort the bound items (list of ViewModel object) ItemsControl based on one of the properties of the items. The ItemsControl is part of a DataTemplate. I thought CollectionViewSource would do the trick, but how do I bind the CollectionViewSource to the ItemsControl. The follwoing code dispays nothing:

<--xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"-->
    <DataTemplate DataType="{x:Type vm:Company}">
        <DataTemplate.Resources>
            <CollectionViewSource x:Key="viewSource" Source="{Binding Employees}">
                <CollectionViewSource.SortDescriptions>
                        <scm:SortDescription PropertyName="ID" />
                    </CollectionViewSource.SortDescriptions>
            </CollectionViewSource>
        </DataTemplate.Resources>
        <Viewbox>
            <ItemsControl ItemsSource="{Binding Source={StaticResource viewSource}}">
                 <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </Viewbox>
    </DataTemplate>
Coyote answered 28/8, 2009 at 16:14 Comment(2)
Anything to do with "Employess" being spelled wrong? Otherwise looks ok to me.Laryngeal
No its not that the problem here seems to be (maybe) that the ViewModel binding ({x:Type vm:Company}) is not known or not evaluated within the ressource scope. Employees is a property of Company btw.Coyote
P
23

Try moving the CollectionViewSource resource to the scope of the Viewbox rather than directly the DataTemplate:

<DataTemplate DataType="{x:Type vm:Company}">
    <Viewbox>
        <Viewbox.Resources>
            <CollectionViewSource x:Key="viewSource" Source="{Binding Employees}">
                <CollectionViewSource.SortDescriptions>
                        <scm:SortDescription PropertyName="ID" />
                    </CollectionViewSource.SortDescriptions>
            </CollectionViewSource>
        </Viewbox.Resources>
        <ItemsControl ItemsSource="{Binding Source={StaticResource viewSource}}">
             <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Viewbox>
</DataTemplate>
Pecoraro answered 29/8, 2009 at 9:57 Comment(1)
As an extension to the answer, the reason is because only the root element of a DataTemplate has it's DataContext set. The DataTemplate itself does not. As DataContext is the only way to Bind to the templated object, you have to put the resource in scope of a non-Null DataContext.Affectional
M
10

I didn't use a DataTemplate or ViewBox to do this. You can choose the sort order by specifying an ItemsControl.Resource....

  <ItemsControl xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
       x:Name="MyItemsControl" Loaded="MyItemsControl_Loaded">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <ItemsControl>
        <ItemsControl.Resources>
          <CollectionViewSource x:Key="Orders" Source="{Binding Orders}">
            <CollectionViewSource.SortDescriptions>
              <scm:SortDescription PropertyName="OrderID" Direction="Ascending"/>
            </CollectionViewSource.SortDescriptions>
          </CollectionViewSource>
        </ItemsControl.Resources>
        <ItemsControl.ItemsSource>
          <Binding Source="{StaticResource Orders}"/>
        </ItemsControl.ItemsSource>
        <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
          </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
          <DataTemplate>
            <TextBlock Text="{Binding OrderID}"/>
          </DataTemplate>
        </ItemsControl.ItemTemplate>
      </ItemsControl>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

Good luck!

Moore answered 8/5, 2012 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.