BlackCoin's Corner

In diesem Blog dreht es sich zu 90 % um den Themenbereich C# .Net

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.


Posted: Nov 29 2009, 03:36 von Lars Schmitt | mit 2 comment(s)
Abgelegt unter:

Kommentare

christian sagte:

beschäftige mich noch nicht lange mit WPF.

in welcher Assembly finde ich den "ExtendetVisualTreeHelper".  Benutze Framework 3.5

# September 24, 2010 9:07

Lars Schmitt sagte:

Sorry die Klasse fehlte wohl noch

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows;

using System.Windows.Media;

namespace Framework.Helper

{

   public class ExtendedVisualTreeHelper

   {

       public static T GetParent<T>(DependencyObject obj) where T : DependencyObject

       {

           DependencyObject parent = VisualTreeHelper.GetParent(obj);

           if (parent == null)

               return default(T);

           if (parent.GetType() == typeof(T))

               return (T)parent;

           else

               return GetParent<T>(parent);

       }

   }

}

# September 24, 2010 9:55
Kommentar abgeben

(verpflichtend) 

(verpflichtend) 

(optional)

(verpflichtend)