Feedback

C# - WPF: MenuItems alphabetisch sortieren

Veröffentlicht von am 20.07.2014
(0 Bewertungen)
Mit der hier gezeigten, angefügten Eigenschaft kann man leicht dafür sorgen, dass alle Elemente eines Menüs bzw. Untermenüs sortiert werden. Dabei werden die Items nach der Header-Eigenschaft sortiert. Separator-Elemente stoppen die Sortierung an ihrer Position. Das heißt, dass immer nur die Elemente zwischen 2 Separatoren sortiert werden.
In der Items-Auflistung dürfen nur MenuItem- und Separator-Elemente enthalten sein.

Benötigte Namespaces
System.Collections.Specialized
System.Windows
System.Linq
System.Windows.Controls

Andere, benötigte Snippets
LINQ Erweiterung: Split
http://dotnet-snippets.de/snippet/linq-erweiterung-split/4893
/// <summary>
/// Stellt Methoden zum Sortieren von <see cref="System.Windows.Controls.MenuItem"/> Elementen bereit.
/// </summary>
public class MenuItemSorter : DependencyObject
{
    /// <summary>
    /// Bezeichnet die angefügte SortItems-Abhängigkeitseigenschaft.
    /// </summary>
    public static readonly DependencyProperty SortItemsProperty = DependencyProperty.RegisterAttached("SortItems", typeof(bool), typeof(MenuItemSorter), new FrameworkPropertyMetadata(false, OnSortItemsChanged));
    /// <summary>
    /// Setzt den Wert der angefügten SortItems-Abhängigkeitseigenschaft.
    /// </summary>
    /// <param name="element">Das <see cref="System.Windows.Controls.Menu"/> oder das <see cref="System.Windows.Controls.MenuItem"/> für das die angefügte Eigenschaft gestezt werden soll.</param>
    /// <param name="value">Der zu setzende Wert.</param>
    public static void SetSortItems(UIElement element, bool value)
    {
        element.SetValue(SortItemsProperty, value);
    }
    /// <summary>
    /// Ruft den Wert der angefügten SortItems-Abhängigkeitseigenschaft ab.
    /// </summary>
    /// <param name="element">Das <see cref="System.Windows.Controls.Menu"/> oder das <see cref="System.Windows.Controls.MenuItem"/> für das die angefügte Eigenschaft ausgelesen werden soll.</param>
    /// <returns>Der Wert der angefügten Abhängigkeitseigenschaft.</returns>

    public static bool GetSortItems(UIElement element)
    {
        return (bool)element.GetValue(SortItemsProperty);
    }

    private static void OnSortItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var items = d is MenuItem ? (d as MenuItem).Items : (d as Menu).Items;

        if ((bool)e.NewValue)
        {
            (items as INotifyCollectionChanged).CollectionChanged += MenuItemSorter_CollectionChanged;
        }
        else
        {
            (items as INotifyCollectionChanged).CollectionChanged -= MenuItemSorter_CollectionChanged;
        }
    }

    static void MenuItemSorter_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        var items = sender as ItemCollection;

        var original = items.Cast<object>().ToArray();//backup items and separators

        (items as INotifyCollectionChanged).CollectionChanged -= MenuItemSorter_CollectionChanged;

        items.Clear();
        var groups = original.Split(x => x is Separator).ToArray();//get MenuItems, separated by Separators
        var seps = original.OfType<Separator>().ToArray();//get the Separators

        int i;
        for (i = 0; i < groups.Length; ++i)
        {
            if (i > 0)
                items.Add(seps[i - 1]);//add the separator

            foreach (var item in groups[i].OrderBy(x => (x as MenuItem).Header))
                items.Add(item);//add MenuItem from this 
        }

        if (seps.Length == i)
            items.Add(seps[i - 1]);//in case a separator is the last Element, add it

        (items as INotifyCollectionChanged).CollectionChanged += MenuItemSorter_CollectionChanged;
    }
}
Abgelegt unter WPF, Menu, MenuItem, Sort, LINQ, AttachedProperty.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!