using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using Developpez.Dotnet.Windows.Properties;
namespace Developpez.Dotnet.Windows.Collections
{
///
/// Représente une collection d'objet qui fournit des notifications quand des éléments sont ajoutés ou
/// supprimés, ou quand la collection entière est modifiée. Fournit une méthode permettant d'ajouter
/// plusieurs objets à la fois en ne déclenchant qu'une seule notification par groupe d'éléments supprimés.
///
/// Type des éléments de la collection
public class RangeObservableCollection : ObservableCollection
{
///
/// Initialise une nouvelle instance vide de RangeObservableCollection<T>
///
public RangeObservableCollection()
{
}
///
/// Initialise une nouvelle instance de RangeObservableCollection<T> en y copiant
/// les éléments de la séquence spécifiée.
///
/// La séquence à partir de laquelle copier les éléments
public RangeObservableCollection(IEnumerable source)
: base(source)
{
}
///
/// Ajoute tous les éléments spécifiés à la collection. Cette méthode ne déclenche qu'une seule notification pour tous les éléments ajoutés,
/// et non une notification par élément ajouté.
///
/// Les éléments à ajouter
public void AddRange(IEnumerable items)
{
items.CheckArgumentNull("items");
var addedItems = new List();
int startingIndex = this.Count;
foreach (var item in items)
{
this.Items.Add(item);
addedItems.Add(item);
}
var args = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add,
addedItems,
startingIndex);
OnCollectionChanged(args);
}
///
/// Insère tous les éléments spécifiés à l'index spécifié de la collection. Cette méthode ne déclenche qu'une seule notification pour tous les éléments insérés,
/// et non une notification par élément inséré.
///
/// L'index auquel insérer les éléments
/// Les éléments à insérer
public void InsertRange(int index, IEnumerable items)
{
index.CheckArgumentOutOfRange("index", 0, this.Count, ExceptionMessages.ArgMustBeInRange);
items.CheckArgumentNull("items");
var addedItems = new List();
int startingIndex = index;
foreach (var item in items)
{
this.Items.Insert(index++, item);
addedItems.Add(item);
}
var args = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add,
addedItems,
startingIndex);
OnCollectionChanged(args);
}
///
/// Supprime le nombre d'éléments spécifié à partir de l'index spécifié de la collection. Cette méthode ne déclenche qu'une seule notification pour tous les éléments supprimés,
/// et non une notification par élément supprimé.
///
/// L'index à partir duquel supprimer les éléments
/// Le nombre d'éléments à supprimer
public void RemoveRange(int index, int count)
{
index.CheckArgumentOutOfRange("index", 0, int.MaxValue, ExceptionMessages.ArgMustBePositive);
count.CheckArgumentOutOfRange("count", 0, int.MaxValue, ExceptionMessages.ArgMustBePositive);
if (index + count > this.Count)
throw new ArgumentException(ExceptionMessages.RemoveRangeBadArgs);
var removedItems = new List();
int startingIndex = index;
for (int i = 0; i < count; i++)
{
removedItems.Add(this.Items[index]);
this.Items.RemoveAt(index);
}
var args = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove,
removedItems,
startingIndex);
OnCollectionChanged(args);
}
///
/// Supprime tous les éléments de la collection qui vérifient la condition spécifiée.
/// Cette méthode déclenche une notification par groupe d'éléments contigus supprimés,
/// et non une notification par élément supprimé.
///
/// La condition à vérifier
public void RemoveAll(Predicate predicate)
{
predicate.CheckArgumentNull("predicate");
int index = 0;
int startIndex = 0;
int count = 0;
while (index < this.Count)
{
if (predicate(this.Items[index]))
{
count++;
index++;
}
else
{
if (count > 0)
{
this.RemoveRange(startIndex, count);
}
startIndex++;
index = startIndex;
count = 0;
}
}
if (count > 0)
{
this.RemoveRange(startIndex, count);
}
}
///
/// Remplace les éléments de la collection par les éléments spécifiés à partir
/// de la position spécifiée. Cette méthode ne déclenche qu'une seule notification
/// pour tous les éléments remplacés, et non une notification par élément remplacé.
///
/// Position à partir de laquelle remplacer les éléments
/// Eléments avec lesquels remplacer les valeurs existantes
public void ReplaceRange(int startIndex, IEnumerable newItems)
{
startIndex.CheckArgumentOutOfRange("startIndex", 0, this.Count - 1, "");
newItems.CheckArgumentNull("newItems");
var newItems2 = newItems.ToList();
if (startIndex + newItems2.Count > this.Count)
throw new ArgumentException(ExceptionMessages.ReplaceRangeBadArgs);
var oldItems = new List();
int index = startIndex;
foreach (var item in newItems2)
{
oldItems.Add(this.Items[index]);
this.Items[index] = item;
index++;
}
var args = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Replace,
newItems2,
oldItems,
startIndex);
OnCollectionChanged(args);
}
}
}