From 03e37f8f693d3a92b88ac8ec2932c4b345aa45d7 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 14 May 2016 20:45:14 +0200 Subject: [PATCH] WIP: More work on primitive virtualization. --- .../Avalonia.Controls.csproj | 1 + .../Presenters/ThingamybobPresenter.cs | 104 ++++++++++++++++++ src/Avalonia.Controls/Thingamybob.cs | 58 ++-------- 3 files changed, 113 insertions(+), 50 deletions(-) create mode 100644 src/Avalonia.Controls/Presenters/ThingamybobPresenter.cs diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index 0bc1e5221e..056fe9e93a 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -69,6 +69,7 @@ + diff --git a/src/Avalonia.Controls/Presenters/ThingamybobPresenter.cs b/src/Avalonia.Controls/Presenters/ThingamybobPresenter.cs new file mode 100644 index 0000000000..a270896441 --- /dev/null +++ b/src/Avalonia.Controls/Presenters/ThingamybobPresenter.cs @@ -0,0 +1,104 @@ +using System; +using Avalonia.Controls.Primitives; +using Avalonia.Media; + +namespace Avalonia.Controls.Presenters +{ + public class ThingamybobPresenter : Decorator, IItemsPresenter, IScrollable + { + private IVirtualizingPanel _panel; + private int _firstIndex; + private int _lastIndex; + + public override void ApplyTemplate() + { + if (_panel == null) + { + _panel = new VirtualizingStackPanel(); + _panel.ArrangeCompleted = CheckPanel; + Child = _panel; + } + } + + public IPanel Panel => _panel; + + Action IScrollable.InvalidateScroll { get; set; } + + Size IScrollable.Extent => new Size(1, 100); + + Vector IScrollable.Offset + { + get + { + return new Vector(0, _firstIndex); + } + + set + { + var count = _lastIndex - _firstIndex; + _firstIndex = (int)Math.Round(value.Y); + _lastIndex = _firstIndex + count; + Renumber(); + } + } + + Size IScrollable.Viewport => new Size(1, _lastIndex - _firstIndex); + Size IScrollable.ScrollSize => new Size(0, 1); + Size IScrollable.PageScrollSize => new Size(0, 1); + + protected override Size ArrangeOverride(Size finalSize) + { + var result = base.ArrangeOverride(finalSize); + CreateItems(); + ((IScrollable)this).InvalidateScroll(); + return result; + } + + private void CreateItems() + { + var randomColor = Color.FromUInt32( + (uint)(0xff000000 + new Random().Next(0xffffff))); + + while (!_panel.IsFull) + { + _panel.Children.Add(new TextBlock + { + Text = "Item " + ++_lastIndex, + Background = new SolidColorBrush(randomColor), + }); + } + } + + private void RemoveItems() + { + var remove = _panel.OverflowCount; + + _panel.Children.RemoveRange( + _panel.Children.Count - remove, + _panel.OverflowCount); + _lastIndex -= remove; + } + + private void Renumber() + { + var index = _firstIndex; + + foreach (TextBlock child in _panel.Children) + { + child.Text = "Item " + ++index; + } + } + + private void CheckPanel() + { + if (!_panel.IsFull) + { + CreateItems(); + } + else if (_panel.OverflowCount > 0) + { + RemoveItems(); + } + } + } +} diff --git a/src/Avalonia.Controls/Thingamybob.cs b/src/Avalonia.Controls/Thingamybob.cs index 7fd251e143..6129b029e8 100644 --- a/src/Avalonia.Controls/Thingamybob.cs +++ b/src/Avalonia.Controls/Thingamybob.cs @@ -1,66 +1,24 @@ using Avalonia.Media; using System; +using Avalonia.Controls.Primitives; +using Avalonia.Controls.Presenters; namespace Avalonia.Controls { public class Thingamybob : Decorator { - private int _lastIndex; + private ScrollViewer _scrollViewer; + private ThingamybobPresenter _presenter; public override void ApplyTemplate() { if (Child == null) { - Child = new VirtualizingStackPanel(); - ((IVirtualizingPanel)Child).ArrangeCompleted = CheckPanel; - } - } - - protected override Size ArrangeOverride(Size finalSize) - { - var result = base.ArrangeOverride(finalSize); - CreateItems(); - return result; - } - - private void CreateItems() - { - var panel = Child as IVirtualizingPanel; - var randomColor = Color.FromUInt32( - (uint)(0xff000000 + new Random().Next(0xffffff))); - - while (!panel.IsFull) - { - panel.Children.Add(new TextBlock - { - Text = "Item " + ++_lastIndex, - Background = new SolidColorBrush(randomColor), - }); - } - } - - private void RemoveItems() - { - var panel = Child as IVirtualizingPanel; - var remove = panel.OverflowCount; - - panel.Children.RemoveRange( - panel.Children.Count - remove, - panel.OverflowCount); - _lastIndex -= remove; - } + _scrollViewer = new ScrollViewer(); + _presenter = new ThingamybobPresenter(); + _scrollViewer.Content = _presenter; - private void CheckPanel() - { - var panel = Child as IVirtualizingPanel; - - if (!panel.IsFull) - { - CreateItems(); - } - else if (panel.OverflowCount > 0) - { - RemoveItems(); + Child = _scrollViewer; } } }