mirror of https://github.com/AMT-Cheif/Stylet.git
143 lines
5.6 KiB
C#
143 lines
5.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections.Specialized;
|
|
using System.ComponentModel;
|
|
|
|
namespace Stylet
|
|
{
|
|
/// <summary>
|
|
/// Represents a collection which is observasble
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public interface IObservableCollection<T> : IList<T>, INotifyPropertyChanged, INotifyCollectionChanged, INotifyPropertyChangedDispatcher
|
|
{
|
|
/// <summary>
|
|
/// Add a range of items
|
|
/// </summary>
|
|
/// <param name="items">Items to add</param>
|
|
void AddRange(IEnumerable<T> items);
|
|
|
|
/// <summary>
|
|
/// Remove a range of items
|
|
/// </summary>
|
|
/// <param name="items">Items to remove</param>
|
|
void RemoveRange(IEnumerable<T> items);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Interface encapsulating IReadOnlyList and INotifyCollectionChanged
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public interface IReadOnlyObservableCollection<T> : IReadOnlyList<T>, INotifyCollectionChanged, INotifyPropertyChangedDispatcher
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// ObservableCollection subclass which supports AddRange and RemoveRange
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class BindableCollection<T> : ObservableCollection<T>, IObservableCollection<T>, IReadOnlyObservableCollection<T>
|
|
{
|
|
private Action<Action> _propertyChangedDispatcher = Execute.DefaultPropertyChangedDispatcher;
|
|
/// <summary>
|
|
/// Dispatcher to use when firing events. Defaults to Execute.DefaultPropertyChangedDispatcher
|
|
/// </summary>
|
|
public Action<Action> PropertyChangedDispatcher
|
|
{
|
|
get { return this._propertyChangedDispatcher; }
|
|
set { this._propertyChangedDispatcher = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// We have to disable notifications when adding individual elements in the AddRange and RemoveRange implementations
|
|
/// </summary>
|
|
private bool isNotifying = true;
|
|
|
|
/// <summary>
|
|
/// Create a new empty BindableCollection
|
|
/// </summary>
|
|
public BindableCollection() : base() { }
|
|
|
|
/// <summary>
|
|
/// Create a new BindableCollection with the given members
|
|
/// </summary>
|
|
/// <param name="collection">The collection from which the elements are copied</param>
|
|
public BindableCollection(IEnumerable<T> collection) : base(collection) { }
|
|
|
|
/// <summary>
|
|
/// Raises the System.Collections.ObjectModel.ObservableCollection{T}.PropertyChanged event with the provided arguments.
|
|
/// </summary>
|
|
/// <param name="e">Arguments of the event being raised.</param>
|
|
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
|
|
{
|
|
if (this.isNotifying)
|
|
this.PropertyChangedDispatcher(() => base.OnPropertyChanged(e));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raises the System.Collections.ObjectModel.ObservableCollection{T}.CollectionChanged event with the provided arguments.
|
|
/// </summary>
|
|
/// <param name="e">Arguments of the event being raised.</param>
|
|
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
|
|
{
|
|
if (this.isNotifying)
|
|
this.PropertyChangedDispatcher(() => base.OnCollectionChanged(e));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a range of items
|
|
/// </summary>
|
|
/// <param name="items">Items to add</param>
|
|
public virtual void AddRange(IEnumerable<T> items)
|
|
{
|
|
var previousNotificationSetting = this.isNotifying;
|
|
this.isNotifying = false;
|
|
var index = Count;
|
|
foreach (var item in items)
|
|
{
|
|
this.InsertItem(index, item);
|
|
index++;
|
|
}
|
|
this.isNotifying = previousNotificationSetting;
|
|
this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
|
|
this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
|
|
// Can't add with a range, or it throws an exception
|
|
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a range of items
|
|
/// </summary>
|
|
/// <param name="items">Items to remove</param>
|
|
public virtual void RemoveRange(IEnumerable<T> items)
|
|
{
|
|
var previousNotificationSetting = this.isNotifying;
|
|
this.isNotifying = false;
|
|
foreach (var item in items)
|
|
{
|
|
var index = IndexOf(item);
|
|
if (index >= 0)
|
|
{
|
|
this.RemoveItem(index);
|
|
}
|
|
}
|
|
this.isNotifying = previousNotificationSetting;
|
|
this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
|
|
this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
|
|
// Can't remove with a range, or it throws an exception
|
|
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raise a change notification indicating that all bindings should be refreshed
|
|
/// </summary>
|
|
public void Refresh()
|
|
{
|
|
this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
|
|
this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
|
|
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
|
}
|
|
}
|
|
}
|