Feedback

C# - WPF: MenuItems alphabetisch sortieren

Veröffentlicht von am 7/20/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!