I am looking for a smart way of binding a ListView
DataSource
property to the set (any collection) of IComparable
custom objects. I would like to have a control real time responding to changes of my collection and have results (in ListView
) sorted using provided by the Interface method.
I suppose that it can be done by creating custom collection inheriting from ObservableCollection<T>
or SortedSet<T>
and binding to such class (which combines the advantages of both). I am new to WPF binding and searching for any hints.
You can do this by using CollectionViewSource
, descendants of which wrap all collections used by WPF controls. You'll need to implement IComparer
though. Here I use a helper class ComparableComparer<T>
which uses IComparable<T>
implementation, but you can put your logic into the Foo
class if you want.
MainWindow.xaml
<Window x:Class="So16368719.MainWindow" x:Name="root"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ListView ItemsSource="{Binding FooItemsSource, ElementName=root}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Name}"/>
</GridView>
</ListView.View>
</ListView>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Data;
namespace So16368719
{
public partial class MainWindow
{
public ObservableCollection<Foo> FooItems { get; set; }
public ListCollectionView FooItemsSource { get; set; }
public MainWindow ()
{
FooItems = new ObservableCollection<Foo> {
new Foo("a"), new Foo("bb"), new Foo("ccc"), new Foo("d"), new Foo("ee"), new Foo("ffff")
};
FooItemsSource = (ListCollectionView)CollectionViewSource.GetDefaultView(FooItems);
FooItemsSource.CustomSort = new ComparableComparer<Foo>();
InitializeComponent();
}
}
public class Foo : IComparable<Foo>
{
public string Name { get; set; }
public Foo (string name)
{
Name = name;
}
public int CompareTo (Foo other)
{
return Name.Length - other.Name.Length;
}
}
public class ComparableComparer<T> : IComparer<T>, IComparer
where T : IComparable<T>
{
public int Compare (T x, T y)
{
return x.CompareTo(y);
}
public int Compare (object x, object y)
{
return Compare((T)x, (T)y);
}
}
}
Note:
ComparableComparer<T>
is quick and dirty. It should also check for nulls.External links: