// Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; using System.Collections; using System.Collections.Specialized; using Avalonia.Controls.Primitives; using Avalonia.Controls.Utils; using Avalonia.Input; using Avalonia.VisualTree; namespace Avalonia.Controls.Presenters { /// /// Base class for classes which handle virtualization for an . /// internal abstract class ItemVirtualizer : IVirtualizingController, IDisposable { private bool disposedValue; /// /// Initializes a new instance of the class. /// /// public ItemVirtualizer(ItemsPresenter owner) { Owner = owner; Items = owner.Items; ItemCount = owner.Items.Count(); } /// /// Gets the which owns the virtualizer. /// public ItemsPresenter Owner { get; } /// /// Gets the which will host the items. /// public IVirtualizingPanel VirtualizingPanel => Owner.Panel as IVirtualizingPanel; /// /// Gets the items to display. /// public IEnumerable Items { get; private set; } /// /// Gets the number of items in . /// public int ItemCount { get; private set; } /// /// Gets or sets the index of the first item displayed in the panel. /// public int FirstIndex { get; protected set; } /// /// Gets or sets the index of the first item beyond those displayed in the panel. /// public int NextIndex { get; protected set; } /// /// Gets a value indicating whether the items should be scroll horizontally or vertically. /// public bool Vertical => VirtualizingPanel.ScrollDirection == Orientation.Vertical; /// /// Gets a value indicating whether logical scrolling is enabled. /// public abstract bool IsLogicalScrollEnabled { get; } /// /// Gets the value of the scroll extent. /// public abstract double ExtentValue { get; } /// /// Gets or sets the value of the current scroll offset. /// public abstract double OffsetValue { get; set; } /// /// Gets the value of the scrollable viewport. /// public abstract double ViewportValue { get; } /// /// Gets the as a . /// public Size Extent => Vertical ? new Size(0, ExtentValue) : new Size(ExtentValue, 0); /// /// Gets the as a . /// public Size Viewport => Vertical ? new Size(0, ViewportValue) : new Size(ViewportValue, 0); /// /// Gets or sets the as a . /// public Vector Offset { get { return Vertical ? new Vector(0, OffsetValue) : new Vector(OffsetValue, 0); } set { OffsetValue = Vertical ? value.Y : value.X; } } /// /// Creates an based on an item presenter's /// . /// /// The items presenter. /// An . public static ItemVirtualizer Create(ItemsPresenter owner) { var virtualizingPanel = owner.Panel as IVirtualizingPanel; var scrollable = (ILogicalScrollable)owner; ItemVirtualizer result = null; if (virtualizingPanel != null && scrollable.InvalidateScroll != null) { switch (owner.VirtualizationMode) { case ItemVirtualizationMode.Simple: result = new ItemVirtualizerSimple(owner); break; } } if (result == null) { result = new ItemVirtualizerNone(owner); } if (virtualizingPanel != null) { virtualizingPanel.Controller = result; } return result; } /// public virtual void UpdateControls() { } /// /// Gets the next control in the specified direction. /// /// The movement direction. /// The control from which movement begins. /// The control. public virtual IControl GetControlInDirection(NavigationDirection direction, IControl from) { return null; } /// /// Called when the items for the presenter change, either because /// has been set, the items collection has been /// modified, or the panel has been created. /// /// The items. /// A description of the change. public virtual void ItemsChanged(IEnumerable items, NotifyCollectionChangedEventArgs e) { Items = items; ItemCount = items.Count(); } /// /// Scrolls the specified item into view. /// /// The item. public virtual void ScrollIntoView(object item) { } /// public virtual void Dispose() { if (VirtualizingPanel != null) { VirtualizingPanel.Controller = null; VirtualizingPanel.Children.Clear(); } Owner.ItemContainerGenerator.Clear(); } /// /// Invalidates the current scroll. /// protected void InvalidateScroll() => ((ILogicalScrollable)Owner).InvalidateScroll(); } }