238 lines
9.1 KiB
C#
238 lines
9.1 KiB
C#
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 Microsoft.Xaml.Behaviors;
|
|
using DTS.Common.Classes;
|
|
using DTS.Common.Interface.Sensors.SensorsList;
|
|
using DTS.Common.Interface.TestSetups.TestSetupsList;
|
|
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);
|
|
var itemsToRemove = new List<object>();
|
|
try
|
|
{
|
|
_isUpdatingSource = true;
|
|
foreach (var item in e.RemovedItems)
|
|
{
|
|
itemsToRemove.Add(item);
|
|
}
|
|
|
|
var itemsToAdd = new List<object>();
|
|
|
|
foreach (var item in e.AddedItems)
|
|
{
|
|
if (!selectedItems.Contains(item))
|
|
{
|
|
itemsToAdd.Add(item);
|
|
}
|
|
}
|
|
var parentType = selectedItems.GetType();
|
|
var type = selectedItems.GetType().GenericTypeArguments[0];
|
|
|
|
if (parentType.IsGenericType && parentType.GetGenericTypeDefinition() == typeof(BulkObservableCollection<>)
|
|
&& type == typeof(IAnalogSensor)||type == typeof(ITestSetup))
|
|
{
|
|
BulkOperations(itemsToRemove, itemsToAdd, selectedItems, type);
|
|
}
|
|
else
|
|
{
|
|
RemoveItems(itemsToRemove, selectedItems);
|
|
AddItems(itemsToAdd, type, selectedItems);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
_isUpdatingSource = false;
|
|
}
|
|
}
|
|
private static void BulkOperations(List<object> itemsToRemove, IList<object> itemsToAdd, IList selectedItems, Type type)
|
|
{
|
|
switch (type.Name)
|
|
{
|
|
case "IAnalogSensor":
|
|
SelectedItemsStatus.SetUpdating(selectedItems, false);
|
|
BulkOperationsAnalogSensor(itemsToRemove, itemsToAdd, selectedItems);
|
|
break;
|
|
case "ITestSetup":
|
|
SelectedItemsStatus.SetUpdating(selectedItems, false);
|
|
BulkOperationsTestSetup(itemsToRemove, itemsToAdd, selectedItems);
|
|
break;
|
|
}
|
|
}
|
|
private static void BulkOperationsAnalogSensor(List<object> itemsToRemove, IList<object> itemsToAdd, IList selectedItems)
|
|
{
|
|
var collection = selectedItems as BulkObservableCollection<IAnalogSensor>;
|
|
var sensorsToAdd = itemsToAdd.Cast<IAnalogSensor>().ToArray();
|
|
var sensorsToRemove = itemsToRemove.Cast<IAnalogSensor>().ToArray();
|
|
RemoveItems(sensorsToRemove, collection);
|
|
AddItems(sensorsToAdd, collection);
|
|
}
|
|
private static void BulkOperationsTestSetup(List<object> itemsToRemove, IList<object> itemsToAdd, IList selectedItems)
|
|
{
|
|
var collection = selectedItems as BulkObservableCollection<ITestSetup>;
|
|
var toAdd = itemsToAdd.Cast<ITestSetup>().ToArray();
|
|
var toRemove = itemsToRemove.Cast<ITestSetup>().ToArray();
|
|
RemoveItems(toRemove, collection);
|
|
AddItems(toAdd, collection);
|
|
}
|
|
private static void RemoveItems(List<object> itemsToRemove, IList selectedItems)
|
|
{
|
|
if (null == itemsToRemove || null == selectedItems) { return; }
|
|
foreach (var item in itemsToRemove)
|
|
{
|
|
selectedItems.Remove(item);
|
|
}
|
|
}
|
|
private static void RemoveItems(IAnalogSensor[] itemsToRemove, BulkObservableCollection<IAnalogSensor> collection)
|
|
{
|
|
if (null == itemsToRemove || !itemsToRemove.Any()) { return; }
|
|
if (null == collection) { return; }
|
|
collection.RemoveRange(itemsToRemove);
|
|
}
|
|
private static void RemoveItems(ITestSetup[] itemsToRemove, BulkObservableCollection<ITestSetup> collection)
|
|
{
|
|
if (null == itemsToRemove || !itemsToRemove.Any()) { return; }
|
|
if (null == collection) { return; }
|
|
collection.RemoveRange(itemsToRemove);
|
|
}
|
|
private static void AddItems(ITestSetup[] itemsToAdd, BulkObservableCollection<ITestSetup> collection)
|
|
{
|
|
if (null == itemsToAdd || !itemsToAdd.Any()) { return; }
|
|
if (null == collection) { return; }
|
|
collection.AddRange(itemsToAdd);
|
|
}
|
|
private static void AddItems(IAnalogSensor[] itemsToAdd, BulkObservableCollection<IAnalogSensor> collection)
|
|
{
|
|
if (null == itemsToAdd || !itemsToAdd.Any()) { return; }
|
|
if (null == collection) { return; }
|
|
collection.AddRange(itemsToAdd);
|
|
}
|
|
private void AddItems(List<object> itemsToAdd, Type type, IList selectedItems)
|
|
{
|
|
foreach (var item in itemsToAdd)
|
|
{
|
|
if (item == itemsToAdd[itemsToAdd.Count-1])
|
|
{
|
|
//if this is the last item, turn notifications back on
|
|
SelectedItemsStatus.SetUpdating(SelectedItems, false);
|
|
}
|
|
|
|
try
|
|
{
|
|
if (type.IsInstanceOfType(item))
|
|
{
|
|
selectedItems.Add(item);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
APILogger.Log(ex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|