Answered by:
sort list box observable collection

Question
-
hi,
my listbox itemsource is "sourceList" - which is MultiSelectCollectionView<string>
i want my list box to be sorted using sort description.but we need to add property with the sort description like below
<CollectionViewSource.SortDescriptions>
<scm:SortDescriptionPropertyName="PropertName"/>
</CollectionViewSource.SortDescriptions>
but there is no such property exist in my item source as my item source itself is property.
so how to sort my list box using sort descrion in xaml it self
Friday, January 3, 2014 10:29 AM
Answers
-
You need to bind the ItemsSource property of the ListBox to a CollectionViewSource and add the SortDescriptions to this CollectionViewSource object.
I don't know what a MultiSelectCollectionView is, but if it is a class that inherits from the ListCollectionView class, you can add the SortDescriptions to it directly:
SourceUserList.SortDescriptions.Add(new System.ComponentModel.SortDescription("", System.ComponentModel.ListSortDirection.Descending));
If you for some reason want to to do this in XAML, you could create a class that inherits from the generic one and define a resource of this type in your window:
public class MultiSelectCollectionViewString : MultiSelectCollectionView<string> { public MultiSelectCollectionViewString(List<string> list) : base(list) { } public MultiSelectCollectionViewString() : base(new List<string>()) { } }
public MainWindow() { InitializeComponent(); MultiSelectCollectionViewString items = this.Resources["sourceList"] as MultiSelectCollectionViewString; for (int i = 0; i < 10; ++i) { items.AddNewItem(i.ToString()); } }
<Window.Resources> <local:MultiSelectCollectionViewString x:Key="sourceList"> <local:MultiSelectCollectionViewString.SortDescriptions> <scm:SortDescription PropertyName="" Direction="Descending"/> </local:MultiSelectCollectionViewString.SortDescriptions> </local:MultiSelectCollectionViewString> </Window.Resources>
<ListBox x:Name="sourceUserList" ItemsSource="{Binding Source={StaticResource sourceList}}, ...
- Proposed as answer by Leo (Apple) Yang Monday, January 6, 2014 1:45 AM
- Marked as answer by Leo (Apple) Yang Thursday, January 9, 2014 7:15 AM
Friday, January 3, 2014 12:00 PM -
Hi,
You can just implement a Custom Sort.
Window x:Class="WpfApplication9.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="MainWindow" x:Name="MyWindow" Height="350" Width="525"> <Window.Resources> <CollectionViewSource x:Key="cvs"> </CollectionViewSource> </Window.Resources> <Grid> <DataGrid x:Name="dgGrid" EnableRowVirtualization="True" AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource cvs}}"> <DataGrid.Columns> <DataGridTemplateColumn Header="Names"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
Code Behind
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.Loaded += MainWindow_Loaded; } void MainWindow_Loaded(object sender, RoutedEventArgs e) { var stringList = new List<string> { "Ball", "Apple", "Cat", "Elephant", "Dog" }; var multiSelectCollectionView = new MultiSelectCollectionView<string>(stringList); dgGrid.ItemsSource = multiSelectCollectionView; MultiSelectCollectionView<string> mscv = CollectionViewSource.GetDefaultView(dgGrid.ItemsSource) as MultiSelectCollectionView<string>; if (mscv != null) { mscv.CustomSort = new CustomStringSort(); } } } public class CustomStringSort : IComparer { int IComparer.Compare(object x, object y) { return ((new CaseInsensitiveComparer()).Compare(x, y)); } }
Output:
srithar
- Proposed as answer by Leo (Apple) Yang Monday, January 6, 2014 1:45 AM
- Marked as answer by Leo (Apple) Yang Thursday, January 9, 2014 7:15 AM
Friday, January 3, 2014 12:14 PM
All replies
-
Hi,
Since you are using collection of string. You can directly use the below code for sorting.
<Window x:Class="ListBoxSort_Learning.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <CollectionViewSource x:Key="SortedItems"> <CollectionViewSource.SortDescriptions> <scm:SortDescription Direction="Ascending"/> </CollectionViewSource.SortDescriptions> </CollectionViewSource> </Window.Resources> <Grid> <ListBox ItemsSource="{Binding Source={StaticResource SortedItems}}"/> </Grid> </Window>
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); CollectionViewSource cvs = FindResource("SortedItems") as CollectionViewSource; ObservableCollection<string> lst = new ObservableCollection<string>(); lst.Add("test"); lst.Add("Abs"); cvs.Source = lst; } }
Let me know if need more info- Edited by AyyappanSubramanian Friday, January 3, 2014 11:03 AM
Friday, January 3, 2014 11:02 AM -
Just omit the PropertyName attribute or specify an empty string:
<CollectionViewSource.SortDescriptions> <scm:SortDescription PropertyName="" Direction="Descending"/> </CollectionViewSource.SortDescriptions>
Friday, January 3, 2014 11:23 AM -
Thanks for reply !!!
i have tried followings
<ListBox x:Name="sourceUserList" ItemsSource="{Binding SourceUserList , ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{StaticResource validationTemplate}" >
<CollectionViewSource >
<CollectionViewSource.SortDescriptions>
<scm:SortDescription Direction="Ascending" PropertyName=""/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</ListBox>not able to sort list box contain
run time my list box contain System.Windows.Data.CollectionView as value
Friday, January 3, 2014 11:49 AM -
Hi
What is type of SourceUserList?
Can you post the code?
Friday, January 3, 2014 11:54 AM -
You need to bind the ItemsSource property of the ListBox to a CollectionViewSource and add the SortDescriptions to this CollectionViewSource object.
I don't know what a MultiSelectCollectionView is, but if it is a class that inherits from the ListCollectionView class, you can add the SortDescriptions to it directly:
SourceUserList.SortDescriptions.Add(new System.ComponentModel.SortDescription("", System.ComponentModel.ListSortDirection.Descending));
If you for some reason want to to do this in XAML, you could create a class that inherits from the generic one and define a resource of this type in your window:
public class MultiSelectCollectionViewString : MultiSelectCollectionView<string> { public MultiSelectCollectionViewString(List<string> list) : base(list) { } public MultiSelectCollectionViewString() : base(new List<string>()) { } }
public MainWindow() { InitializeComponent(); MultiSelectCollectionViewString items = this.Resources["sourceList"] as MultiSelectCollectionViewString; for (int i = 0; i < 10; ++i) { items.AddNewItem(i.ToString()); } }
<Window.Resources> <local:MultiSelectCollectionViewString x:Key="sourceList"> <local:MultiSelectCollectionViewString.SortDescriptions> <scm:SortDescription PropertyName="" Direction="Descending"/> </local:MultiSelectCollectionViewString.SortDescriptions> </local:MultiSelectCollectionViewString> </Window.Resources>
<ListBox x:Name="sourceUserList" ItemsSource="{Binding Source={StaticResource sourceList}}, ...
- Proposed as answer by Leo (Apple) Yang Monday, January 6, 2014 1:45 AM
- Marked as answer by Leo (Apple) Yang Thursday, January 9, 2014 7:15 AM
Friday, January 3, 2014 12:00 PM -
Hi,
You can just implement a Custom Sort.
Window x:Class="WpfApplication9.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="MainWindow" x:Name="MyWindow" Height="350" Width="525"> <Window.Resources> <CollectionViewSource x:Key="cvs"> </CollectionViewSource> </Window.Resources> <Grid> <DataGrid x:Name="dgGrid" EnableRowVirtualization="True" AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource cvs}}"> <DataGrid.Columns> <DataGridTemplateColumn Header="Names"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
Code Behind
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.Loaded += MainWindow_Loaded; } void MainWindow_Loaded(object sender, RoutedEventArgs e) { var stringList = new List<string> { "Ball", "Apple", "Cat", "Elephant", "Dog" }; var multiSelectCollectionView = new MultiSelectCollectionView<string>(stringList); dgGrid.ItemsSource = multiSelectCollectionView; MultiSelectCollectionView<string> mscv = CollectionViewSource.GetDefaultView(dgGrid.ItemsSource) as MultiSelectCollectionView<string>; if (mscv != null) { mscv.CustomSort = new CustomStringSort(); } } } public class CustomStringSort : IComparer { int IComparer.Compare(object x, object y) { return ((new CaseInsensitiveComparer()).Compare(x, y)); } }
Output:
srithar
- Proposed as answer by Leo (Apple) Yang Monday, January 6, 2014 1:45 AM
- Marked as answer by Leo (Apple) Yang Thursday, January 9, 2014 7:15 AM
Friday, January 3, 2014 12:14 PM