Articles
This is an enhancement of the ObservableCollecton. It brings additional behaviors like the AddRange, RemoveAll, Sort and you also can get a command if one of the inner elements sends the property changed.

Usage
<UserControl x:Class="DW.SharpTools.Demo.EnhancedObservableCollectionControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel>
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Center">
<Button Content="Add Alphabet" Click="AddAlphabet_Click" />
<Button Content="Sort" Click="Sort_Click" />
<Button Content="Revert" Click="Revert_Click" />
</StackPanel>
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</DockPanel>
</UserControl>
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace DW.SharpTools.Demo
{
public partial class EnhancedObservableCollectionControl : UserControl
{
public EnhancedObservableCollectionControl()
{
InitializeComponent();
DataContext = this;
Items = new EnhancedObservableCollection<char>();
}
public EnhancedObservableCollection<char> Items { get; set; }
private void AddAlphabet_Click(object sender, System.Windows.RoutedEventArgs e)
{
Items.AddRange(Enumerable.Range('a', 26).Select(i => (char)i));
}
private void Sort_Click(object sender, RoutedEventArgs e)
{
Items.Sort();
}
private void Revert_Click(object sender, RoutedEventArgs e)
{
Items.Sort(Revert);
}
private static int Revert(char lhv, char rhv)
{
return rhv.CompareTo(lhv);
}
}
}