diff --git a/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml b/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml index dfe8be2cec..d0631d2cbd 100644 --- a/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml +++ b/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml @@ -6,19 +6,20 @@ ItemsRepeater A data-driven collection control that incorporates a flexible layout system, custom views, and virtualization. - + Stack - Vertical Stack - Horizontal UniformGrid - Vertical UniformGrid - Horizontal + - + diff --git a/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs b/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs index 214de89253..1a607342f3 100644 --- a/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs +++ b/samples/ControlCatalog/Pages/ItemsRepeaterPage.xaml.cs @@ -1,8 +1,11 @@ +using System; using System.Linq; using Avalonia.Controls; using Avalonia.Controls.Primitives; +using Avalonia.Input; using Avalonia.Layout; using Avalonia.Markup.Xaml; +using ControlCatalog.ViewModels; namespace ControlCatalog.Pages { @@ -16,7 +19,8 @@ namespace ControlCatalog.Pages this.InitializeComponent(); _repeater = this.FindControl("repeater"); _scroller = this.FindControl("scroller"); - DataContext = Enumerable.Range(1, 100000).Select(i => $"Item {i}" ).ToArray(); + _repeater.PointerPressed += RepeaterClick; + DataContext = new ItemsRepeaterPageViewModel(); } private void InitializeComponent() @@ -67,5 +71,11 @@ namespace ControlCatalog.Pages break; } } + + private void RepeaterClick(object sender, PointerPressedEventArgs e) + { + var item = (e.Source as TextBlock)?.DataContext as string; + ((ItemsRepeaterPageViewModel)DataContext).SelectedItem = item; + } } } diff --git a/samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs b/samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs new file mode 100644 index 0000000000..436a479441 --- /dev/null +++ b/samples/ControlCatalog/ViewModels/ItemsRepeaterPageViewModel.cs @@ -0,0 +1,27 @@ +using System.Collections.ObjectModel; +using System.Linq; +using ReactiveUI; + +namespace ControlCatalog.ViewModels +{ + public class ItemsRepeaterPageViewModel : ReactiveObject + { + private int newItemIndex = 1; + + public ItemsRepeaterPageViewModel() + { + Items = new ObservableCollection( + Enumerable.Range(1, 100000).Select(i => $"Item {i}")); + } + + public ObservableCollection Items { get; } + + public string SelectedItem { get; set; } + + public void AddItem() + { + var index = SelectedItem != null ? Items.IndexOf(SelectedItem) : -1; + Items.Insert(index + 1, $"New Item {newItemIndex++}"); + } + } +} diff --git a/src/Avalonia.Controls/Repeater/ItemsRepeater.cs b/src/Avalonia.Controls/Repeater/ItemsRepeater.cs index 44783e2c97..257c1b2399 100644 --- a/src/Avalonia.Controls/Repeater/ItemsRepeater.cs +++ b/src/Avalonia.Controls/Repeater/ItemsRepeater.cs @@ -707,9 +707,9 @@ namespace Avalonia.Controls } } - private void InvalidateArrangeForLayout(object sender, EventArgs e) => InvalidateMeasure(); + private void InvalidateMeasureForLayout(object sender, EventArgs e) => InvalidateMeasure(); - private void InvalidateMeasureForLayout(object sender, EventArgs e) => InvalidateArrange(); + private void InvalidateArrangeForLayout(object sender, EventArgs e) => InvalidateArrange(); private VirtualizingLayoutContext GetLayoutContext() { diff --git a/src/Avalonia.Controls/Repeater/ItemsSourceView.cs b/src/Avalonia.Controls/Repeater/ItemsSourceView.cs index 732ba8501c..02ead7ef36 100644 --- a/src/Avalonia.Controls/Repeater/ItemsSourceView.cs +++ b/src/Avalonia.Controls/Repeater/ItemsSourceView.cs @@ -35,9 +35,11 @@ namespace Avalonia.Controls { Contract.Requires(source != null); - _inner = source as IList; - - if (_inner == null && source is IEnumerable objectEnumerable) + if (source is IList list) + { + _inner = list; + } + else if (source is IEnumerable objectEnumerable) { _inner = new List(objectEnumerable); } diff --git a/src/Avalonia.Layout/UniformGridLayoutState.cs b/src/Avalonia.Layout/UniformGridLayoutState.cs index 4557a78d37..e6d75bcf35 100644 --- a/src/Avalonia.Layout/UniformGridLayoutState.cs +++ b/src/Avalonia.Layout/UniformGridLayoutState.cs @@ -72,12 +72,6 @@ namespace Avalonia.Layout _cachedFirstElement.Measure(availableSize); - // This doesn't need to be done in the UWP version and I'm not sure why. If we - // don't do this here, and we receive a recycled element then it will be shown - // at its previous arrange point, but we don't want it shown at all until its - // arranged. - _cachedFirstElement.Arrange(new Rect(-10000.0, -10000.0, 0, 0)); - SetSize(_cachedFirstElement, layoutItemWidth, LayoutItemHeight, availableSize, stretch, orientation, minRowSpacing, minColumnSpacing); // See if we can move ownership to the flow algorithm. If we can, we do not need a local cache.