ListView Sortierung, mit der Hilfe von Attached Properties
Ja ich weiß, ein WPF ListView um eine Sortierungsfunktion zu erweitern ist kein Hexenwerk, noch nicht einmal für jemanden, der noch nicht ganz so firm in der Entwicklung ist. Jedoch findet man im Netz sehr selten eine Implementierung, die das ganze über ein, oder für ein besseres Handling lieber zwei Attached Properties realisiert.
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace Framework.Helper
{
public class ListViewColumnSorter
{
#region Fields (2)
// Using a DependencyProperty as the backing store for SortDirection. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SortDirectionProperty =
DependencyProperty.RegisterAttached("SortDirection", typeof(SortDirection), typeof(ListViewColumnSorter), new UIPropertyMetadata(SortDirection.None, OnSortDirectionChanged));
// Using a DependencyProperty as the backing store for SortingPropertyName. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SortingPropertyNameProperty =
DependencyProperty.RegisterAttached("SortingPropertyName", typeof(string), typeof(ListViewColumnSorter), new UIPropertyMetadata(String.Empty, OnPropertyChanged));
#endregion Fields
#region Methods (8)
// Public Methods (4)
public static SortDirection GetSortDirection(DependencyObject obj)
{
return (SortDirection)obj.GetValue(SortDirectionProperty);
}
public static string GetSortingPropertyName(DependencyObject obj)
{
return (string)obj.GetValue(SortingPropertyNameProperty);
}
public static void SetSortDirection(DependencyObject obj, SortDirection value)
{
obj.SetValue(SortDirectionProperty, value);
}
public static void SetSortingPropertyName(DependencyObject obj, string value)
{
obj.SetValue(SortingPropertyNameProperty, value);
}
// Private Methods (4)
static ICollectionView GetSource(object dataSource)
{
if (dataSource is CollectionViewSource)
return (dataSource as CollectionViewSource).View;
else
return CollectionViewSource.GetDefaultView(dataSource);
}
static void gvch_Click(object sender, RoutedEventArgs e)
{
switch (GetSortDirection(sender as DependencyObject))
{
case SortDirection.None:
SetSortDirection(sender as DependencyObject, SortDirection.Ascending);
break;
case SortDirection.Ascending:
SetSortDirection(sender as DependencyObject, SortDirection.Descending);
break;
case SortDirection.Descending:
SetSortDirection(sender as DependencyObject, SortDirection.None);
break;
default:
SetSortDirection(sender as DependencyObject, SortDirection.None);
break;
}
}
private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
GridViewColumnHeader gvch = sender as GridViewColumnHeader;
if (gvch != null)
if (!string.IsNullOrEmpty(e.NewValue.ToString()))
gvch.Click += gvch_Click;
else
{
gvch.Click -= gvch_Click;
SetSortDirection(sender, SortDirection.None);
}
}
private static void OnSortDirectionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
ListView lstView = ExtendetVisualTreeHelper.GetParent<ListView>(sender as DependencyObject);
ICollectionView view = GetSource(lstView.DataContext);
string pName = GetSortingPropertyName(sender);
for (int i = view.SortDescriptions.Count - 1; i > -1; i--)
{
if (view.SortDescriptions<img src="http://dotnet-forum.de/emoticons/emotion-55.gif" alt="Idea" />.PropertyName == pName)
view.SortDescriptions.RemoveAt(i);
}
if (lstView != null)
{
switch (GetSortDirection(sender as DependencyObject))
{
case SortDirection.Ascending:
view.SortDescriptions.Add(new SortDescription(pName, ListSortDirection.Ascending));
break;
case SortDirection.Descending:
view.SortDescriptions.Add(new SortDescription(pName, ListSortDirection.Descending));
break;
default:
break;
}
}
}
#endregion Methods
}
public enum SortDirection : int
{
None = 0,
Ascending,
Descending
}
}
der eigene enum, wird an dieser Stelle benötigt, da die .Net Enum ListSortDirection leider nur Ascending und Decending enthält, wir aber an dieser Stelle auch eine None benötigen.
Durch das zweite Atached Property, machen wir es an dieser Stelle nicht nur einfacher, sondern auch die aktuelle Sortierung, mit Hilfe von Templates und Triggern an der Oberfläche Visualisieren.