A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

89 lines
3.5 KiB

using System;
using System.Collections.Specialized;
using Avalonia.Reactive;
using Avalonia.Utilities;
namespace Avalonia.Collections
{
public static class NotifyCollectionChangedExtensions
{
/// <summary>
/// Gets a weak observable for the CollectionChanged event.
/// </summary>
/// <param name="collection">The collection.</param>
/// <returns>An observable.</returns>
public static IObservable<NotifyCollectionChangedEventArgs> GetWeakCollectionChangedObservable(
this INotifyCollectionChanged collection)
{
_ = collection ?? throw new ArgumentNullException(nameof(collection));
return new WeakCollectionChangedObservable(new WeakReference<INotifyCollectionChanged>(collection));
}
/// <summary>
/// Subscribes to the CollectionChanged event using a weak subscription.
/// </summary>
/// <param name="collection">The collection.</param>
/// <param name="handler">
/// An action called when the collection event is raised.
/// </param>
/// <returns>A disposable used to terminate the subscription.</returns>
public static IDisposable WeakSubscribe(
this INotifyCollectionChanged collection,
NotifyCollectionChangedEventHandler handler)
{
_ = collection ?? throw new ArgumentNullException(nameof(collection));
_ = handler ?? throw new ArgumentNullException(nameof(handler));
return collection.GetWeakCollectionChangedObservable()
.Subscribe(e => handler(collection, e));
}
/// <summary>
/// Subscribes to the CollectionChanged event using a weak subscription.
/// </summary>
/// <param name="collection">The collection.</param>
/// <param name="handler">
/// An action called when the collection event is raised.
/// </param>
/// <returns>A disposable used to terminate the subscription.</returns>
public static IDisposable WeakSubscribe(
this INotifyCollectionChanged collection,
Action<NotifyCollectionChangedEventArgs> handler)
{
_ = collection ?? throw new ArgumentNullException(nameof(collection));
_ = handler ?? throw new ArgumentNullException(nameof(handler));
return collection.GetWeakCollectionChangedObservable().Subscribe(handler);
}
private class WeakCollectionChangedObservable : LightweightObservableBase<NotifyCollectionChangedEventArgs>,
IWeakEventSubscriber<NotifyCollectionChangedEventArgs>
{
private WeakReference<INotifyCollectionChanged> _sourceReference;
public WeakCollectionChangedObservable(WeakReference<INotifyCollectionChanged> source)
{
_sourceReference = source;
}
public void OnEvent(object? sender,
WeakEvent ev,
NotifyCollectionChangedEventArgs e)
{
PublishNext(e);
}
protected override void Initialize()
{
if (_sourceReference.TryGetTarget(out var instance))
WeakEvents.CollectionChanged.Subscribe(instance, this);
}
protected override void Deinitialize()
{
if (_sourceReference.TryGetTarget(out var instance))
WeakEvents.CollectionChanged.Unsubscribe(instance, this);
}
}
}
}