From c1b2e2d44dc303625e91ee8c2cf56e437e2a1d7a Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 20 Aug 2020 21:41:11 +0200 Subject: [PATCH] Refactored ItemSourceView. - Inner list needs to be a non-generic `IList` because `IList` is no covariant. - Moved out of the Repeater directory as it's now general-purpose. --- .../{Repeater => }/ItemsSourceView.cs | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) rename src/Avalonia.Controls/{Repeater => }/ItemsSourceView.cs (84%) diff --git a/src/Avalonia.Controls/Repeater/ItemsSourceView.cs b/src/Avalonia.Controls/ItemsSourceView.cs similarity index 84% rename from src/Avalonia.Controls/Repeater/ItemsSourceView.cs rename to src/Avalonia.Controls/ItemsSourceView.cs index e84d97784a..2836937b79 100644 --- a/src/Avalonia.Controls/Repeater/ItemsSourceView.cs +++ b/src/Avalonia.Controls/ItemsSourceView.cs @@ -15,23 +15,17 @@ using Avalonia.Controls.Utils; namespace Avalonia.Controls { /// - /// Represents a standardized view of the supported interactions between a given ItemsSource - /// object and an control. + /// Represents a standardized view of the supported interactions between a given + /// or and its items. /// - /// - /// Components written to work with ItemsRepeater should consume the - /// via ItemsSourceView since this provides a normalized - /// view of the Items. That way, each component does not need to know if the source is an - /// IEnumerable, an IList, or something else. - /// public class ItemsSourceView : INotifyCollectionChanged, IDisposable, IReadOnlyList { /// - /// Gets an empty + /// Gets an empty /// public static ItemsSourceView Empty { get; } = new ItemsSourceView(Array.Empty()); - private readonly IList _inner; + private readonly IList _inner; private INotifyCollectionChanged? _notifyCollectionChanged; /// @@ -47,17 +41,17 @@ namespace Avalonia.Controls { source = source ?? throw new ArgumentNullException(nameof(source)); - if (source is IList list) + if (source is IList list) { _inner = list; } - else if (source is IEnumerable objectEnumerable) + else if (source is IEnumerable enumerable) { - _inner = new List(objectEnumerable); + _inner = new List(enumerable); } else { - _inner = new List(source.Cast()); + _inner = new List(source.Cast()); } ListenToCollectionChanges(); @@ -102,9 +96,9 @@ namespace Avalonia.Controls /// /// The index. /// The item. - public T GetAt(int index) => _inner[index]; + public T GetAt(int index) => _inner is IList typed ? typed[index] : (T)_inner[index]; - public int IndexOf(T item) => _inner.IndexOf(item); + public int IndexOf(object? item) => _inner.IndexOf(item); public static ItemsSourceView GetOrCreate(IEnumerable? items) { @@ -148,7 +142,9 @@ namespace Avalonia.Controls throw new NotImplementedException(); } - public IEnumerator GetEnumerator() => _inner.GetEnumerator(); + public IEnumerator GetEnumerator() => _inner is IList typed ? + typed.GetEnumerator() : _inner.Cast().GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => _inner.GetEnumerator(); internal void AddListener(ICollectionChangedListener listener) @@ -187,7 +183,7 @@ namespace Avalonia.Controls } } - public class ItemsSourceView : ItemsSourceView + public class ItemsSourceView : ItemsSourceView { public ItemsSourceView(IEnumerable source) : base(source)