|
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
namespace CodeProject.Windows.Markup
{
public static class Selection
{
private class SelectedItemsWatcher
{
DependencyObject obj;
IList source;
bool inChangeHandler;
internal SelectedItemsWatcher(DependencyObject obj)
{
this.obj = obj;
Type type = obj.GetType();
EventInfo eventInfo = type.GetEvent("SelectionChanged");
Type handlerType = eventInfo.EventHandlerType;
MethodInfo methodInfo = GetType().GetMethod("OnSelectionChanged",
BindingFlags.NonPublic | BindingFlags.Instance);
Delegate handler = Delegate.CreateDelegate(handlerType, this, methodInfo);
MethodInfo addHandler = eventInfo.GetAddMethod();
addHandler.Invoke(obj, new object[] { handler });
}
private IList GetSelectedItems()
{
Type type = obj.GetType();
PropertyInfo propertyInfo = type.GetProperty("SelectedItems");
return (IList)propertyInfo.GetValue(obj, null);
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (inChangeHandler)
return;
inChangeHandler = true;
try
{
foreach (object item in e.RemovedItems)
{
source.Remove(item);
}
foreach (object item in e.AddedItems)
{
source.Add(item);
}
}
finally
{
inChangeHandler = false;
}
}
internal void SelectedItemsChanged(DependencyPropertyChangedEventArgs e)
{
IList selectedItems = GetSelectedItems();
inChangeHandler = true;
try
{
if (e.OldValue != null)
{
INotifyCollectionChanged collectionChanged = (INotifyCollectionChanged)e.OldValue;
collectionChanged.CollectionChanged -= OnSelectedItemsCollectionChanged;
}
selectedItems.Clear();
if (e.NewValue != null)
{
source = (IList)e.NewValue;
foreach (object item in source)
{
selectedItems.Add(item);
}
INotifyCollectionChanged collectionChanged = (INotifyCollectionChanged)e.NewValue;
collectionChanged.CollectionChanged += OnSelectedItemsCollectionChanged;
}
}
finally
{
inChangeHandler = false;
}
}
private void OnSelectedItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (inChangeHandler)
return;
inChangeHandler = true;
try
{
IList selectedItems = GetSelectedItems();
selectedItems.Clear();
foreach (object item in (IList)sender)
{
selectedItems.Add(item);
}
}
finally
{
inChangeHandler = false;
}
}
}
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(Selection),
new FrameworkPropertyMetadata(null, OnSelectedItemsChanged));
private static readonly DependencyProperty SelectedItemsWatcherProperty =
DependencyProperty.RegisterAttached("SelectedItemsWatcher", typeof(SelectedItemsWatcher), typeof(Selection),
new FrameworkPropertyMetadata(null, OnSelectedItemsWatcherChanged));
public static IList GetSelectedItems(DependencyObject obj)
{
return (IList)obj.GetValue(SelectedItemsProperty);
}
public static void SetSelectedItems(DependencyObject obj, IList value)
{
obj.SetValue(SelectedItemsProperty, value);
}
private static SelectedItemsWatcher GetSelectedItemsWatcher(DependencyObject obj)
{
return (SelectedItemsWatcher)obj.GetValue(SelectedItemsWatcherProperty);
}
private static void SetSelectedItemsWatcher(DependencyObject obj, SelectedItemsWatcher value)
{
obj.SetValue(SelectedItemsWatcherProperty, value);
}
private static void OnSelectedItemsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
SelectedItemsWatcher watcher = GetSelectedItemsWatcher(sender);
if (watcher == null)
{
watcher = new SelectedItemsWatcher(sender);
SetSelectedItemsWatcher(sender, watcher);
}
watcher.SelectedItemsChanged(e);
}
private static void OnSelectedItemsWatcherChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}
private static void OnSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Windows developer with 10+ years experience working in the banking industry.