Browse Source

Expose pre/post collection changed events.

Instead of implementing `ICollectionChangedListener` on `SelectionNodeBase`. We may want to expose this publicly at some point.
pull/10589/head
Steven Kirk 4 years ago
parent
commit
21574f5607
  1. 39
      src/Avalonia.Controls/ItemsSourceView.cs
  2. 38
      src/Avalonia.Controls/Selection/SelectionNodeBase.cs

39
src/Avalonia.Controls/ItemsSourceView.cs

@ -27,6 +27,7 @@ namespace Avalonia.Controls
private readonly IList _inner;
private NotifyCollectionChangedEventHandler? _collectionChanged;
private NotifyCollectionChangedEventHandler? _preCollectionChanged;
private NotifyCollectionChangedEventHandler? _postCollectionChanged;
private bool _listening;
@ -70,7 +71,7 @@ namespace Avalonia.Controls
/// Gets a value that indicates whether the items source can provide a unique key for each item.
/// </summary>
/// <remarks>
/// TODO: Not yet implemented in Avalonia.
/// Not implemented in Avalonia, preserved here for ItemsRepeater's usage.
/// </remarks>
internal bool HasKeyIndexMapping => false;
@ -92,6 +93,25 @@ namespace Avalonia.Controls
}
}
/// <summary>
/// Occurs when a collection has finished changing and all <see cref="CollectionChanged"/>
/// event handlers have been notified.
/// </summary>
internal event NotifyCollectionChangedEventHandler? PreCollectionChanged
{
add
{
AddListenerIfNecessary();
_preCollectionChanged += value;
}
remove
{
_preCollectionChanged -= value;
RemoveListenerIfNecessary();
}
}
/// <summary>
/// Occurs when a collection has finished changing and all <see cref="CollectionChanged"/>
/// event handlers have been notified.
@ -229,6 +249,7 @@ namespace Avalonia.Controls
void ICollectionChangedListener.PreChanged(INotifyCollectionChanged sender, NotifyCollectionChangedEventArgs e)
{
_preCollectionChanged?.Invoke(this, e);
}
void ICollectionChangedListener.Changed(INotifyCollectionChanged sender, NotifyCollectionChangedEventArgs e)
@ -241,22 +262,6 @@ namespace Avalonia.Controls
_postCollectionChanged?.Invoke(this, e);
}
internal void AddListener(ICollectionChangedListener listener)
{
if (Inner is INotifyCollectionChanged incc)
{
CollectionChangedEventManager.Instance.AddListener(incc, listener);
}
}
internal void RemoveListener(ICollectionChangedListener listener)
{
if (Inner is INotifyCollectionChanged incc)
{
CollectionChangedEventManager.Instance.RemoveListener(incc, listener);
}
}
/// <summary>
/// Retrieves the index of the item that has the specified unique identifier (key).
/// </summary>

38
src/Avalonia.Controls/Selection/SelectionNodeBase.cs

@ -2,7 +2,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using Avalonia.Controls.Utils;
namespace Avalonia.Controls.Selection
{
@ -10,7 +9,7 @@ namespace Avalonia.Controls.Selection
/// Base class for selection models.
/// </summary>
/// <typeparam name="T">The type of the element being selected.</typeparam>
public abstract class SelectionNodeBase<T> : ICollectionChangedListener
public abstract class SelectionNodeBase<T>
{
private IEnumerable? _source;
private bool _rangesEnabled;
@ -24,12 +23,28 @@ namespace Avalonia.Controls.Selection
get => _source;
set
{
void OnPreChanged(object? sender, NotifyCollectionChangedEventArgs e) => OnSourceCollectionChangeStarted();
void OnChanged(object? sender, NotifyCollectionChangedEventArgs e) => OnSourceCollectionChanged(e);
void OnPostChanged(object? sender, NotifyCollectionChangedEventArgs e) => OnSourceCollectionChangeFinished();
if (_source != value)
{
ItemsView?.RemoveListener(this);
if (ItemsView is not null)
{
ItemsView.PreCollectionChanged -= OnPreChanged;
ItemsView.CollectionChanged -= OnChanged;
ItemsView.PostCollectionChanged -= OnPostChanged;
}
_source = value;
ItemsView = value is not null ? ItemsSourceView.GetOrCreate<T>(value) : null;
ItemsView?.AddListener(this);
if (ItemsView is not null)
{
ItemsView.PreCollectionChanged += OnPreChanged;
ItemsView.CollectionChanged += OnChanged;
ItemsView.PostCollectionChanged += OnPostChanged;
}
}
}
}
@ -73,21 +88,6 @@ namespace Avalonia.Controls.Selection
}
}
void ICollectionChangedListener.PreChanged(INotifyCollectionChanged sender, NotifyCollectionChangedEventArgs e)
{
OnSourceCollectionChangeStarted();
}
void ICollectionChangedListener.Changed(INotifyCollectionChanged sender, NotifyCollectionChangedEventArgs e)
{
OnSourceCollectionChanged(e);
}
void ICollectionChangedListener.PostChanged(INotifyCollectionChanged sender, NotifyCollectionChangedEventArgs e)
{
OnSourceCollectionChangeFinished();
}
/// <summary>
/// Called when the source collection starts changing.
/// </summary>

Loading…
Cancel
Save