Browse Source

Merge branch 'master' into awaitablerun-animations

pull/1774/head
Jeremy Koritzinsky 8 years ago
committed by GitHub
parent
commit
b60c4abccb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/Avalonia.Controls/Presenters/ItemVirtualizer.cs
  2. 36
      src/Avalonia.Controls/Presenters/ItemsPresenter.cs
  3. 30
      src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs
  4. 9
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs

5
src/Avalonia.Controls/Presenters/ItemVirtualizer.cs

@ -161,6 +161,11 @@ namespace Avalonia.Controls.Presenters
/// <returns>An <see cref="ItemVirtualizer"/>.</returns> /// <returns>An <see cref="ItemVirtualizer"/>.</returns>
public static ItemVirtualizer Create(ItemsPresenter owner) public static ItemVirtualizer Create(ItemsPresenter owner)
{ {
if (owner.Panel == null)
{
return null;
}
var virtualizingPanel = owner.Panel as IVirtualizingPanel; var virtualizingPanel = owner.Panel as IVirtualizingPanel;
var scrollable = (ILogicalScrollable)owner; var scrollable = (ILogicalScrollable)owner;
ItemVirtualizer result = null; ItemVirtualizer result = null;

36
src/Avalonia.Controls/Presenters/ItemsPresenter.cs

@ -22,7 +22,6 @@ namespace Avalonia.Controls.Presenters
nameof(VirtualizationMode), nameof(VirtualizationMode),
defaultValue: ItemVirtualizationMode.None); defaultValue: ItemVirtualizationMode.None);
private ItemVirtualizer _virtualizer;
private bool _canHorizontallyScroll; private bool _canHorizontallyScroll;
private bool _canVerticallyScroll; private bool _canVerticallyScroll;
@ -76,21 +75,27 @@ namespace Avalonia.Controls.Presenters
/// <inheritdoc/> /// <inheritdoc/>
bool ILogicalScrollable.IsLogicalScrollEnabled bool ILogicalScrollable.IsLogicalScrollEnabled
{ {
get { return _virtualizer?.IsLogicalScrollEnabled ?? false; } get { return Virtualizer?.IsLogicalScrollEnabled ?? false; }
} }
/// <inheritdoc/> /// <inheritdoc/>
Size IScrollable.Extent => _virtualizer.Extent; Size IScrollable.Extent => Virtualizer?.Extent ?? Size.Empty;
/// <inheritdoc/> /// <inheritdoc/>
Vector IScrollable.Offset Vector IScrollable.Offset
{ {
get { return _virtualizer.Offset; } get { return Virtualizer?.Offset ?? new Vector(); }
set { _virtualizer.Offset = CoerceOffset(value); } set
{
if (Virtualizer != null)
{
Virtualizer.Offset = CoerceOffset(value);
}
}
} }
/// <inheritdoc/> /// <inheritdoc/>
Size IScrollable.Viewport => _virtualizer.Viewport; Size IScrollable.Viewport => Virtualizer?.Viewport ?? Bounds.Size;
/// <inheritdoc/> /// <inheritdoc/>
Action ILogicalScrollable.InvalidateScroll { get; set; } Action ILogicalScrollable.InvalidateScroll { get; set; }
@ -101,6 +106,8 @@ namespace Avalonia.Controls.Presenters
/// <inheritdoc/> /// <inheritdoc/>
Size ILogicalScrollable.PageScrollSize => new Size(0, 1); Size ILogicalScrollable.PageScrollSize => new Size(0, 1);
internal ItemVirtualizer Virtualizer { get; private set; }
/// <inheritdoc/> /// <inheritdoc/>
bool ILogicalScrollable.BringIntoView(IControl target, Rect targetRect) bool ILogicalScrollable.BringIntoView(IControl target, Rect targetRect)
{ {
@ -110,29 +117,30 @@ namespace Avalonia.Controls.Presenters
/// <inheritdoc/> /// <inheritdoc/>
IControl ILogicalScrollable.GetControlInDirection(NavigationDirection direction, IControl from) IControl ILogicalScrollable.GetControlInDirection(NavigationDirection direction, IControl from)
{ {
return _virtualizer?.GetControlInDirection(direction, from); return Virtualizer?.GetControlInDirection(direction, from);
} }
public override void ScrollIntoView(object item) public override void ScrollIntoView(object item)
{ {
_virtualizer?.ScrollIntoView(item); Virtualizer?.ScrollIntoView(item);
} }
/// <inheritdoc/> /// <inheritdoc/>
protected override Size MeasureOverride(Size availableSize) protected override Size MeasureOverride(Size availableSize)
{ {
return _virtualizer?.MeasureOverride(availableSize) ?? Size.Empty; return Virtualizer?.MeasureOverride(availableSize) ?? Size.Empty;
} }
protected override Size ArrangeOverride(Size finalSize) protected override Size ArrangeOverride(Size finalSize)
{ {
return _virtualizer?.ArrangeOverride(finalSize) ?? Size.Empty; return Virtualizer?.ArrangeOverride(finalSize) ?? Size.Empty;
} }
/// <inheritdoc/> /// <inheritdoc/>
protected override void PanelCreated(IPanel panel) protected override void PanelCreated(IPanel panel)
{ {
_virtualizer = ItemVirtualizer.Create(this); Virtualizer?.Dispose();
Virtualizer = ItemVirtualizer.Create(this);
((ILogicalScrollable)this).InvalidateScroll?.Invoke(); ((ILogicalScrollable)this).InvalidateScroll?.Invoke();
if (!Panel.IsSet(KeyboardNavigation.DirectionalNavigationProperty)) if (!Panel.IsSet(KeyboardNavigation.DirectionalNavigationProperty))
@ -149,7 +157,7 @@ namespace Avalonia.Controls.Presenters
protected override void ItemsChanged(NotifyCollectionChangedEventArgs e) protected override void ItemsChanged(NotifyCollectionChangedEventArgs e)
{ {
_virtualizer?.ItemsChanged(Items, e); Virtualizer?.ItemsChanged(Items, e);
} }
private Vector CoerceOffset(Vector value) private Vector CoerceOffset(Vector value)
@ -162,8 +170,8 @@ namespace Avalonia.Controls.Presenters
private void VirtualizationModeChanged(AvaloniaPropertyChangedEventArgs e) private void VirtualizationModeChanged(AvaloniaPropertyChangedEventArgs e)
{ {
_virtualizer?.Dispose(); Virtualizer?.Dispose();
_virtualizer = ItemVirtualizer.Create(this); Virtualizer = ItemVirtualizer.Create(this);
((ILogicalScrollable)this).InvalidateScroll?.Invoke(); ((ILogicalScrollable)this).InvalidateScroll?.Invoke();
} }
} }

30
src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Specialized; using System.Collections.Specialized;
using Avalonia.Collections;
using Avalonia.Controls.Generators; using Avalonia.Controls.Generators;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Styling; using Avalonia.Styling;
@ -40,6 +41,7 @@ namespace Avalonia.Controls.Presenters
ItemsControl.MemberSelectorProperty.AddOwner<ItemsPresenterBase>(); ItemsControl.MemberSelectorProperty.AddOwner<ItemsPresenterBase>();
private IEnumerable _items; private IEnumerable _items;
private IDisposable _itemsSubscription;
private bool _createdPanel; private bool _createdPanel;
private IItemContainerGenerator _generator; private IItemContainerGenerator _generator;
@ -63,24 +65,12 @@ namespace Avalonia.Controls.Presenters
set set
{ {
if (_createdPanel) _itemsSubscription?.Dispose();
{ _itemsSubscription = null;
INotifyCollectionChanged incc = _items as INotifyCollectionChanged;
if (incc != null)
{
incc.CollectionChanged -= ItemsCollectionChanged;
}
}
if (_createdPanel && value != null) if (_createdPanel && value is INotifyCollectionChanged incc)
{ {
INotifyCollectionChanged incc = value as INotifyCollectionChanged; _itemsSubscription = incc.WeakSubscribe(ItemsCollectionChanged);
if (incc != null)
{
incc.CollectionChanged += ItemsCollectionChanged;
}
} }
SetAndRaise(ItemsProperty, ref _items, value); SetAndRaise(ItemsProperty, ref _items, value);
@ -233,11 +223,9 @@ namespace Avalonia.Controls.Presenters
_createdPanel = true; _createdPanel = true;
INotifyCollectionChanged incc = Items as INotifyCollectionChanged; if (_itemsSubscription == null && Items is INotifyCollectionChanged incc)
if (incc != null)
{ {
incc.CollectionChanged += ItemsCollectionChanged; _itemsSubscription = incc.WeakSubscribe(ItemsCollectionChanged);
} }
PanelCreated(Panel); PanelCreated(Panel);
@ -263,4 +251,4 @@ namespace Avalonia.Controls.Presenters
(e.NewValue as IItemsPresenterHost)?.RegisterItemsPresenter(this); (e.NewValue as IItemsPresenterHost)?.RegisterItemsPresenter(this);
} }
} }
} }

9
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs

@ -195,6 +195,15 @@ namespace Avalonia.Controls.UnitTests.Presenters
} }
} }
[Fact]
public void Should_Not_Create_Virtualizer_Before_Panel()
{
var target = CreateTarget();
Assert.Null(target.Panel);
Assert.Null(target.Virtualizer);
}
[Fact] [Fact]
public void Changing_VirtualizationMode_None_To_Simple_Should_Update_Control() public void Changing_VirtualizationMode_None_To_Simple_Should_Update_Control()
{ {

Loading…
Cancel
Save