|
|
@@ -10,15 +10,47 @@ using System.Linq;
|
|
|
|
|
|
namespace Perspex.Collections
|
|
|
{
|
|
|
+ /// <summary>
|
|
|
+ /// Describes the action notified on a clear of a <see cref="PerspexList{T}"/>.
|
|
|
+ /// </summary>
|
|
|
+ public enum ResetBehavior
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// Clearing the list notifies a with a
|
|
|
+ /// <see cref="NotifyCollectionChangedAction.Reset"/>.
|
|
|
+ /// </summary>
|
|
|
+ Reset,
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Clearing the list notifies a with a
|
|
|
+ /// <see cref="NotifyCollectionChangedAction.Remove"/>.
|
|
|
+ /// </summary>
|
|
|
+ Remove,
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// A notifying list.
|
|
|
/// </summary>
|
|
|
/// <typeparam name="T">The type of the list items.</typeparam>
|
|
|
/// <remarks>
|
|
|
+ /// <para>
|
|
|
/// PerspexList is similar to <see cref="System.Collections.ObjectModel.ObservableCollection{T}"/>
|
|
|
- /// except that when the <see cref="Clear"/> method is called, it notifies with a
|
|
|
- /// <see cref="NotifyCollectionChangedAction.Remove"/> action, passing the items that were
|
|
|
- /// removed.
|
|
|
+ /// with a few added features:
|
|
|
+ /// </para>
|
|
|
+ ///
|
|
|
+ /// <list type="bullet">
|
|
|
+ /// <item>
|
|
|
+ /// It can be configured to notify the <see cref="CollectionChanged"/> event with a
|
|
|
+ /// <see cref="NotifyCollectionChangedAction.Remove"/> action instead of a
|
|
|
+ /// <see cref="NotifyCollectionChangedAction.Reset"/> when the list is cleared by
|
|
|
+ /// setting <see cref="ResetBehavior"/> to <see cref="ResetBehavior.Remove"/>.
|
|
|
+ /// removed
|
|
|
+ /// </item>
|
|
|
+ /// <item>
|
|
|
+ /// A <see cref="Validate"/> function can be used to validate each item before insertion.
|
|
|
+ /// removed
|
|
|
+ /// </item>
|
|
|
+ /// </list>
|
|
|
/// </remarks>
|
|
|
public class PerspexList<T> : IPerspexList<T>, IList, INotifyCollectionChanged, INotifyPropertyChanged
|
|
|
{
|
|
|
@@ -65,6 +97,17 @@ namespace Perspex.Collections
|
|
|
/// </summary>
|
|
|
public int Count => _inner.Count;
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Gets or sets the reset behavior of the list.
|
|
|
+ /// </summary>
|
|
|
+ public ResetBehavior ResetBehavior { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Gets or sets a validation routine that can be used to validate items before they are
|
|
|
+ /// added.
|
|
|
+ /// </summary>
|
|
|
+ public Action<T> Validate { get; set; }
|
|
|
+
|
|
|
/// <inheritdoc/>
|
|
|
bool IList.IsFixedSize => false;
|
|
|
|
|
|
@@ -97,6 +140,8 @@ namespace Perspex.Collections
|
|
|
|
|
|
set
|
|
|
{
|
|
|
+ Validate?.Invoke(value);
|
|
|
+
|
|
|
T old = _inner[index];
|
|
|
_inner[index] = value;
|
|
|
|
|
|
@@ -128,6 +173,7 @@ namespace Perspex.Collections
|
|
|
/// <param name="item">The item.</param>
|
|
|
public void Add(T item)
|
|
|
{
|
|
|
+ Validate?.Invoke(item);
|
|
|
int index = _inner.Count;
|
|
|
_inner.Add(item);
|
|
|
NotifyAdd(new[] { item }, index);
|
|
|
@@ -141,6 +187,14 @@ namespace Perspex.Collections
|
|
|
{
|
|
|
Contract.Requires<ArgumentNullException>(items != null);
|
|
|
|
|
|
+ if (Validate != null)
|
|
|
+ {
|
|
|
+ foreach (var item in items)
|
|
|
+ {
|
|
|
+ Validate(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
int index = _inner.Count;
|
|
|
_inner.AddRange(items);
|
|
|
NotifyAdd((items as IList) ?? items.ToList(), index);
|
|
|
@@ -153,7 +207,7 @@ namespace Perspex.Collections
|
|
|
{
|
|
|
var old = _inner;
|
|
|
_inner = new List<T>();
|
|
|
- NotifyRemove(old, 0);
|
|
|
+ NotifyReset(old);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -204,6 +258,7 @@ namespace Perspex.Collections
|
|
|
/// <param name="item">The item.</param>
|
|
|
public void Insert(int index, T item)
|
|
|
{
|
|
|
+ Validate?.Invoke(item);
|
|
|
_inner.Insert(index, item);
|
|
|
NotifyAdd(new[] { item }, index);
|
|
|
}
|
|
|
@@ -217,6 +272,14 @@ namespace Perspex.Collections
|
|
|
{
|
|
|
Contract.Requires<ArgumentNullException>(items != null);
|
|
|
|
|
|
+ if (Validate != null)
|
|
|
+ {
|
|
|
+ foreach (var item in items)
|
|
|
+ {
|
|
|
+ Validate(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
_inner.InsertRange(index, items);
|
|
|
NotifyAdd((items as IList) ?? items.ToList(), index);
|
|
|
}
|
|
|
@@ -367,5 +430,30 @@ namespace Perspex.Collections
|
|
|
|
|
|
NotifyCountChanged();
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Raises the <see cref="CollectionChanged"/> event with a reset action.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="t">The items that were removed.</param>
|
|
|
+ private void NotifyReset(IList t)
|
|
|
+ {
|
|
|
+ if (CollectionChanged != null)
|
|
|
+ {
|
|
|
+ NotifyCollectionChangedEventArgs e;
|
|
|
+
|
|
|
+ if (ResetBehavior == ResetBehavior.Reset)
|
|
|
+ {
|
|
|
+ e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, t, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ CollectionChanged(this, e);
|
|
|
+ }
|
|
|
+
|
|
|
+ NotifyCountChanged();
|
|
|
+ }
|
|
|
}
|
|
|
}
|