Um Datenlisten besser sortieren und filtern zu können gibt es (wie bereits in WPF) nun CollectionViews in Silverlight 3.
Damit kann man eine View vor eine List von beliebigen Objekten schalten, die dann entsprechend manipuliert werden kann, ohne die Originalliste zu beeinflussen.
Auch Master-/Detailbindung ist damit leichter möglich.
Zuerst sollte man in den Ressource z.B. des UserControls eine CollectionViewSource anlegen:
<UserControl.Resources>
<CollectionViewSource x:Name="CollectionVS"
Filter="CollectionVS_Filter" />
</UserControl.Resources>
Filter ist ein Event, das gefeuert wird, um die Daten der Collection View manuell zu filtern. Folgende Implementierung wählt zum Beispiel nur Personen, deren Vorname mit „M“ beginnt:
private void CollectionVS_Filter(object sender, FilterEventArgs e)
{
var s = e.Item as Person;
if (s != null && s.Vorname.StartsWith("M"))
e.Accepted = true;
else
e.Accepted = false;
}
Wichtig: Es sollte dabei immer nur EIN Filter Eventhandler gesetzt werden!
Nun kann z.B. das ListBox Control zur Visualisierung verwendet werden, indem es die ItemsSource auf die CollectionViewSource setzt:
<ListBox Grid.Column="0" Name="CVSList"
ItemsSource="{Binding Source={StaticResource CollectionVS}}"
DisplayMemberPath="Nachname" />
Schließlich muss die CollectionViewSource noch mit Personen Objekten gefüttert werden, die dann gefiltert dargestellt werden.
var list = new List<Person>()
{
new Person(){
Vorname = "Max", Nachname="Knor"
},
new Person(){
Vorname = "Mark", Nachname="Ballmer"
},
new Person(){
Vorname = "Phil", Nachname="Gates"
}
};
this.CollectionVS.Source = list;
In der Liste werden nun nur Ballmer und mein Name, jedoch nicht Gates angezeigt.

Um eine zusätzliche Sortierung vorzunehmen, muss eine oder mehrere SortDescriptions angelegt werden:
this.CollectionVS.SortDescriptions.Add(
new SortDescription("Vorname", ListSortDirection.Descending));
Die Standard CollectionViewSource besitzt zwar eine GroupDescriptions Eigenschaft, jedoch ist diese derzeit nicht implementiert. Sie könnte aber in abgeleiteten ViewSources selbst implementiert werden.
Interessant ist die CollectionViewSource besonders für das Szenario Master-/Detailbindung:

Neben der Liste sollen jeweils Detaildaten zur ausgewählten Person angezeigt werden. Die einfachste Lösung für dieses häufige Problem ist nun die CollectionViewSource als Datenquelle für beide Bereiche zu verwenden.
<Grid DataContext="{Binding Source={StaticResource CollectionVS}}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0" Name="CVSList" SelectionMode="Single"
ItemsSource="{Binding}" DisplayMemberPath="Nachname" />
<StackPanel Grid.Column="1" Margin="10">
<TextBlock Text="{Binding Path=Vorname}" />
<TextBlock Text="{Binding Path=Nachname}" />
</StackPanel>
</Grid>
Dadurch dass bei ItemSource sowie den einzelnen Text Eigenschaften keine Source Eigenschaft gesetzt ist, übernehmen sie den darüberliegenden DataContext, also in dem Fall die CollectionViewSource. Diese kümmert sich darum, über den CurrentItem Wert beide Bereiche miteinander zu synchronisieren – das heißt, wird in der Liste eine andere Person ausgewählt, ändert sich auch der Detailbereich automatisch mit.
knom