Files
DP44/Common/DTS.Common.Utilities/ActiveUpdateList.cs
2026-04-17 14:55:32 -04:00

354 lines
12 KiB
C#

/*
* ActiveUpdateList.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.Collections.Generic;
using System.Linq;
namespace DTS.Common.Utilities
{ ///
/// <summary>
/// An extension of the standard <see cref="T:List"/> class that provides active notification to
/// registered callbacks whenever items are added to or removed from the list.
/// </summary>
///
/// <typeparam name="T">
/// The type of object contained in this list.
/// </typeparam>
///
public class ActiveUpdateList<T> : ExceptionalList<T>
{ ///
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
public ActiveUpdateList()
{
}
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="capacity">
/// The number of elements that the list can initially store.
/// </param>
///
public ActiveUpdateList(int capacity)
: base(capacity)
{
}
/// <summary>
/// Initialize an instance of this class.
/// </summary>
///
/// <param name="collection">
/// The collection whose elements are copied to the new list.
/// </param>
///
public ActiveUpdateList(IEnumerable<T> collection)
: base(collection)
{
}
/// <summary>
/// The argument type passed to "on items added" and "on items removed" callbacks. It contains
/// a list of the items that have been added/removed.
/// </summary>
public class EventArgs : System.EventArgs
{
/// <summary>
/// construct an empty collection of items
/// </summary>
public EventArgs() { }
/// <summary>
/// construct a collection of items
/// </summary>
/// <param name="items">arguments to add</param>
public EventArgs(IEnumerable<T> items) { Items = items; }
public IEnumerable<T> Items { get; private set; }
}
/// <summary>
/// The type of the callbacks issued by this class.
/// </summary>
///
/// <param name="sender">
/// The <see cref="object"/> responsible for generating this event.
/// </param>
///
/// <param name="args">
/// The <see cref="T:ActiveUpdateList.EventArgs"/> for this event.
/// </param>
///
public delegate void EventHandler(object sender, EventArgs args);
/// <summary>
/// The event generated whenever items are added to this object's list.
/// </summary>
public event EventHandler OnItemsAdded;
/// <summary>
/// The event generated whenever items are removed from this list.
/// </summary>
public event EventHandler OnItemsRemoved;
/// <summary>
/// Adds an object to the end of the <see cref="T:ActiveUpdateList"/>.
/// </summary>
///
/// <param name="item">
/// The item to be added to this list.
/// </param>
///
/// <exception cref="T:ActiveUpdateList.Exception">
/// All exceptions generated by this method will be nested in one of these.
/// </exception>
///
public new void Add(T item)
{
try
{
base.Add(item);
var addList = new List<T>();
addList.Add(item);
OnItemsAdded?.Invoke(this, new EventArgs(addList));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem adding item to active update list", ex);
}
}
/// <summary>
/// Adds the elements of the specified collection to the end of the <see cref="T:ActiveUpdateList"/>.
/// </summary>
///
/// <param name="collection">
/// The collection to the added to this list.
/// </param>
///
/// <exception cref="T:ActiveUpdateList.Exception">
/// All exceptions generated by this method will be nested in one of these.
/// </exception>
///
public new void AddRange(IEnumerable<T> collection)
{
try
{
var enumerable = collection as T[] ?? collection.ToArray();
base.AddRange(enumerable);
OnItemsAdded?.Invoke(this, new EventArgs(enumerable));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem adding range to active update list", ex);
}
}
/// <summary>
/// Removes all elements from the <see cref="T:ActiveUpdateList"/>.
/// </summary>
///
/// <exception cref="T:ActiveUpdateList.Exception">
/// All exceptions generated by this method will be nested in one of these.
/// </exception>
///
public new void Clear()
{
try
{
var removedItems = new List<T>();
foreach (var item in this)
removedItems.Add(item);
base.Clear();
OnItemsRemoved?.Invoke(this, new EventArgs(removedItems));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem clearing active update list", ex);
}
}
/// <summary>
/// Inserts the elements of a collection into the <see cref="T:ActiveUpdateList"/> at the
/// specified index.
/// </summary>
///
/// <param name="index">
/// The zero-based index at which the new elements should be inserted.
/// </param>
///
/// <param name="collection">
/// The collection whose elements should be inserted into the T:ActiveUpdateList.
/// The collection itself cannot be null, but it can contain elements that are
/// null, if type T is a reference type.
/// </param>
///
/// <exception cref="T:ActiveUpdateList.Exception">
/// All exceptions generated by this method will be nested in one of these.
/// </exception>
///
public new void InsertRange(int index, IEnumerable<T> collection)
{
try
{
var enumerable = collection as T[] ?? collection.ToArray();
base.InsertRange(index, enumerable);
OnItemsAdded?.Invoke(this, new EventArgs(enumerable));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem inserting range in active update list", ex);
}
}
/// <summary>
/// Removes the first occurrence of a specific object from the <see cref="T:ActiveUpdateList"/>.
/// </summary>
///
/// <param name="item">
/// The object to remove from the <see cref="T:System.Collections.Generic.List" />. The value
/// can be null for reference types.
/// </param>
///
/// <returns>
/// <see cref="bool"/> true if item is successfully removed; otherwise, false. This method also
/// returns false if item was not found in the <see cref="T:ActiveUpdateList"/>.
/// </returns>
///
/// <exception cref="T:ActiveUpdateList.Exception">
/// All exceptions generated by this method will be nested in one of these.
/// </exception>
///
public new bool Remove(T item)
{
try
{
var success = base.Remove(item);
var removeList = new List<T>();
removeList.Add(item);
OnItemsRemoved?.Invoke(this, new EventArgs(removeList));
return success;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem removing item from active update list", ex);
}
}
/// <summary>
/// Removes the all the elements that match the conditions defined by the specified
/// predicate.
/// </summary>
///
/// <param name="match">
/// The <see cref="T:System.Predicate"/> delegate that defines the conditions of the elements
/// to remove.
/// </param>
///
/// <returns>
/// The number of elements removed from the <see cref="T:ActiveUpdateList"/>
/// </returns>
///
/// <exception cref="T:ActiveUpdateList.Exception">
/// All exceptions generated by this method will be nested in one of these.
/// </exception>
///
public new int RemoveAll(Predicate<T> match)
{
try
{
var removeList = FindAll(match);
var numberOfItemsRemoved = base.RemoveAll(match);
OnItemsRemoved?.Invoke(this, new EventArgs(removeList));
return numberOfItemsRemoved;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem removing all matching items from active update list", ex);
}
}
/// <summary>
/// Removes the element at the specified index of the <see cref="T:ActiveUpdateList"/>.
/// </summary>
///
/// <param name="index">
/// The zero-based index of the element to remove.
/// </param>
///
/// <exception cref="T:ActiveUpdateList.Exception">
/// All exceptions generated by this method will be nested in one of these.
/// </exception>
///
public new void RemoveAt(int index)
{
try
{
var removeList = new List<T>();
removeList.Add(base[index]);
base.RemoveAt(index);
OnItemsRemoved?.Invoke(this, new EventArgs(removeList));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem removing item at specified index from active update list", ex);
}
}
/// <summary>
/// Removes a range of elements from the <see cref="T:ActiveUpdateList"/>.
/// </summary>
///
/// <param name="index">
/// The zero-based starting index of the range of elements to remove.
/// </param>
///
/// <param name="count">
/// The number of elements to remove.
/// </param>
///
/// <exception cref="T:ActiveUpdateList.Exception">
/// All exceptions generated by this method will be nested in one of these.
/// </exception>
///
public new void RemoveRange(int index, int count)
{
try
{
var removeList = GetRange(index, count);
base.RemoveRange(index, count);
OnItemsRemoved?.Invoke(this, new EventArgs(removeList));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem removing range from active update list", ex);
}
}
}
}