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;
}
}
Kommentare zum Snippet