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>
public static ItemVirtualizer Create(ItemsPresenter owner)
{
if (owner.Panel == null)
{
return null;
}
var virtualizingPanel = owner.Panel as IVirtualizingPanel;
var scrollable = (ILogicalScrollable)owner;
ItemVirtualizer result = null;

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

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

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

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

Loading…
Cancel
Save