Domanda

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.

È stato utile?

Soluzione

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:

  • Implementation of ComparableComparer<T> is quick and dirty. It should also check for nulls.
  • You should use MVVM pattern and not code-behind.

External links:

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top