init
This commit is contained in:
160
Common/DTS.CommonCore/Behaviors/MultiSelectionBehavior.cs
Normal file
160
Common/DTS.CommonCore/Behaviors/MultiSelectionBehavior.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
using DTS.Common.Enums;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Interactivity;
|
||||
namespace DTS.Common.Behaviors
|
||||
{
|
||||
public class MultiSelectionBehavior : Behavior<ListBox>
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
base.OnAttached();
|
||||
if (SelectedItems != null)
|
||||
{
|
||||
AssociatedObject.SelectedItems.Clear();
|
||||
foreach (var item in SelectedItems)
|
||||
{
|
||||
AssociatedObject.SelectedItems.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IList SelectedItems
|
||||
{
|
||||
get => (IList)GetValue(SelectedItemsProperty);
|
||||
set => SetValue(SelectedItemsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedItemsProperty =
|
||||
DependencyProperty.Register("SelectedItems", typeof(IList), typeof(MultiSelectionBehavior), new UIPropertyMetadata(null, SelectedItemsChanged));
|
||||
|
||||
private static void SelectedItemsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var behavior = o as MultiSelectionBehavior;
|
||||
if (behavior == null)
|
||||
return;
|
||||
|
||||
|
||||
if (e.OldValue is INotifyCollectionChanged oldValue)
|
||||
{
|
||||
oldValue.CollectionChanged -= behavior.SourceCollectionChanged;
|
||||
behavior.AssociatedObject.SelectionChanged -= behavior.ListBoxSelectionChanged;
|
||||
}
|
||||
if (e.NewValue is INotifyCollectionChanged newValue)
|
||||
{
|
||||
behavior.AssociatedObject.SelectedItems.Clear();
|
||||
foreach (var item in (IEnumerable)newValue)
|
||||
{
|
||||
behavior.AssociatedObject.SelectedItems.Add(item);
|
||||
}
|
||||
|
||||
behavior.AssociatedObject.SelectionChanged += behavior.ListBoxSelectionChanged;
|
||||
newValue.CollectionChanged += behavior.SourceCollectionChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isUpdatingTarget;
|
||||
private bool _isUpdatingSource;
|
||||
|
||||
private void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (_isUpdatingSource)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_isUpdatingTarget = true;
|
||||
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var item in e.OldItems)
|
||||
{
|
||||
AssociatedObject.SelectedItems.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var item in e.NewItems)
|
||||
{
|
||||
AssociatedObject.SelectedItems.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.Action == NotifyCollectionChangedAction.Reset)
|
||||
{
|
||||
AssociatedObject.SelectedItems.Clear();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isUpdatingTarget = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (_isUpdatingTarget)
|
||||
return;
|
||||
|
||||
var selectedItems = SelectedItems;
|
||||
if (selectedItems == null)
|
||||
return;
|
||||
//this could be a bulk operation, turn off notifications if consumer is paying attention
|
||||
SelectedItemsStatus.SetUpdating(SelectedItems, true);
|
||||
try
|
||||
{
|
||||
_isUpdatingSource = true;
|
||||
foreach (var item in e.RemovedItems)
|
||||
{
|
||||
selectedItems.Remove(item);
|
||||
}
|
||||
|
||||
var itemsToAdd = new List<object>();
|
||||
|
||||
foreach (var item in e.AddedItems)
|
||||
{
|
||||
if (!selectedItems.Contains(item))
|
||||
{
|
||||
itemsToAdd.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
var type = selectedItems.GetType().GenericTypeArguments[0];
|
||||
|
||||
foreach (var item in itemsToAdd)
|
||||
{
|
||||
if (item == itemsToAdd.Last())
|
||||
{
|
||||
//if this is the last item, turn notifications back on
|
||||
SelectedItemsStatus.SetUpdating(SelectedItems, false);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (type.IsAssignableFrom(item.GetType()))
|
||||
{
|
||||
selectedItems.Add(item);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isUpdatingSource = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user