diff --git a/src/Avalonia.Controls/ItemsSourceView.cs b/src/Avalonia.Controls/ItemsSourceView.cs
index 1fa8f6a5cf..416b909219 100644
--- a/src/Avalonia.Controls/ItemsSourceView.cs
+++ b/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.
///
///
- /// TODO: Not yet implemented in Avalonia.
+ /// Not implemented in Avalonia, preserved here for ItemsRepeater's usage.
///
internal bool HasKeyIndexMapping => false;
@@ -92,6 +93,25 @@ namespace Avalonia.Controls
}
}
+ ///
+ /// Occurs when a collection has finished changing and all
+ /// event handlers have been notified.
+ ///
+ internal event NotifyCollectionChangedEventHandler? PreCollectionChanged
+ {
+ add
+ {
+ AddListenerIfNecessary();
+ _preCollectionChanged += value;
+ }
+
+ remove
+ {
+ _preCollectionChanged -= value;
+ RemoveListenerIfNecessary();
+ }
+ }
+
///
/// Occurs when a collection has finished changing and all
/// 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);
- }
- }
-
///
/// Retrieves the index of the item that has the specified unique identifier (key).
///
diff --git a/src/Avalonia.Controls/Selection/SelectionNodeBase.cs b/src/Avalonia.Controls/Selection/SelectionNodeBase.cs
index 22db0cbb6c..caeff61f07 100644
--- a/src/Avalonia.Controls/Selection/SelectionNodeBase.cs
+++ b/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.
///
/// The type of the element being selected.
- public abstract class SelectionNodeBase : ICollectionChangedListener
+ public abstract class SelectionNodeBase
{
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(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();
- }
-
///
/// Called when the source collection starts changing.
///