mirror of
https://github.com/4sval/FModel.git
synced 2026-03-22 01:34:37 -05:00
116 lines
3.5 KiB
C#
116 lines
3.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections.Specialized;
|
|
using System.ComponentModel;
|
|
|
|
namespace FModel.Framework;
|
|
|
|
public class FullyObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged
|
|
{
|
|
/// <summary>
|
|
/// Occurs when a property is changed within an item.
|
|
/// </summary>
|
|
public event EventHandler<ItemPropertyChangedEventArgs> ItemPropertyChanged;
|
|
|
|
public FullyObservableCollection()
|
|
{
|
|
}
|
|
|
|
public FullyObservableCollection(List<T> list) : base(list)
|
|
{
|
|
ObserveAll();
|
|
}
|
|
|
|
public FullyObservableCollection(IEnumerable<T> enumerable) : base(enumerable)
|
|
{
|
|
ObserveAll();
|
|
}
|
|
|
|
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
|
|
{
|
|
if (e.Action is NotifyCollectionChangedAction.Remove or
|
|
NotifyCollectionChangedAction.Replace)
|
|
{
|
|
foreach (T item in e.OldItems)
|
|
item.PropertyChanged -= ChildPropertyChanged;
|
|
}
|
|
|
|
if (e.Action is NotifyCollectionChangedAction.Add or
|
|
NotifyCollectionChangedAction.Replace)
|
|
{
|
|
foreach (T item in e.NewItems)
|
|
item.PropertyChanged += ChildPropertyChanged;
|
|
}
|
|
|
|
base.OnCollectionChanged(e);
|
|
}
|
|
|
|
protected void OnItemPropertyChanged(ItemPropertyChangedEventArgs e)
|
|
{
|
|
ItemPropertyChanged?.Invoke(this, e);
|
|
}
|
|
|
|
protected void OnItemPropertyChanged(int index, PropertyChangedEventArgs e)
|
|
{
|
|
OnItemPropertyChanged(new ItemPropertyChangedEventArgs(index, e));
|
|
}
|
|
|
|
protected override void ClearItems()
|
|
{
|
|
foreach (T item in Items)
|
|
item.PropertyChanged -= ChildPropertyChanged;
|
|
|
|
base.ClearItems();
|
|
}
|
|
|
|
private void ObserveAll()
|
|
{
|
|
foreach (var item in Items)
|
|
item.PropertyChanged += ChildPropertyChanged;
|
|
}
|
|
|
|
private void ChildPropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
var typedSender = (T) sender;
|
|
var i = Items.IndexOf(typedSender);
|
|
|
|
if (i < 0)
|
|
throw new ArgumentException("Received property notification from item not in collection");
|
|
|
|
OnItemPropertyChanged(i, e);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Provides data for the <see cref="FullyObservableCollection{T}.ItemPropertyChanged"/> event.
|
|
/// </summary>
|
|
public class ItemPropertyChangedEventArgs : PropertyChangedEventArgs
|
|
{
|
|
/// <summary>
|
|
/// Gets the index in the collection for which the property change has occurred.
|
|
/// </summary>
|
|
/// <value>
|
|
/// Index in parent collection.
|
|
/// </value>
|
|
public int CollectionIndex { get; }
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="ItemPropertyChangedEventArgs"/> class.
|
|
/// </summary>
|
|
/// <param name="index">The index in the collection of changed item.</param>
|
|
/// <param name="name">The name of the property that changed.</param>
|
|
public ItemPropertyChangedEventArgs(int index, string name) : base(name)
|
|
{
|
|
CollectionIndex = index;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="ItemPropertyChangedEventArgs"/> class.
|
|
/// </summary>
|
|
/// <param name="index">The index.</param>
|
|
/// <param name="args">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
|
|
public ItemPropertyChangedEventArgs(int index, PropertyChangedEventArgs args) : this(index, args.PropertyName)
|
|
{
|
|
}
|
|
} |