Browse Source

Delegate ScrollIntoView to ItemVirtualizer.

This doesn't make sense for ItemVirtualizationMode.Simple so we do
nothing here.
Steven Kirk 9 years ago
parent
commit
03c138ff90

+ 26 - 20
samples/XamlTestApplicationPcl/TestScrollable.cs

@@ -3,6 +3,7 @@ using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls.Primitives;
 using Avalonia.Media;
+using Avalonia.VisualTree;
 
 namespace XamlTestApplication
 {
@@ -54,6 +55,31 @@ namespace XamlTestApplication
             }
         }
 
+        public override void Render(DrawingContext context)
+        {
+            var y = 0.0;
+
+            for (var i = (int)_offset.Y; i < itemCount; ++i)
+            {
+                using (var line = new FormattedText(
+                    "Item " + (i + 1),
+                    TextBlock.GetFontFamily(this),
+                    TextBlock.GetFontSize(this),
+                    TextBlock.GetFontStyle(this),
+                    TextAlignment.Left,
+                    TextBlock.GetFontWeight(this)))
+                {
+                    context.DrawText(Brushes.Black, new Point(-_offset.X, y), line);
+                    y += _lineSize.Height;
+                }
+            }
+        }
+
+        public bool BringIntoView(IVisual target, Rect targetRect)
+        {
+            throw new NotImplementedException();
+        }
+
         protected override Size MeasureOverride(Size availableSize)
         {
             using (var line = new FormattedText(
@@ -77,25 +103,5 @@ namespace XamlTestApplication
             InvalidateScroll?.Invoke();
             return finalSize;
         }
-
-        public override void Render(DrawingContext context)
-        {
-            var y = 0.0;
-
-            for (var i = (int)_offset.Y; i < itemCount; ++i)
-            {
-                using (var line = new FormattedText(
-                    "Item " + (i + 1),
-                    TextBlock.GetFontFamily(this),
-                    TextBlock.GetFontSize(this),
-                    TextBlock.GetFontStyle(this),
-                    TextAlignment.Left,
-                    TextBlock.GetFontWeight(this)))
-                {
-                    context.DrawText(Brushes.Black, new Point(-_offset.X, y), line);
-                    y += _lineSize.Height;
-                }
-            }
-        }
     }
 }

+ 6 - 0
src/Avalonia.Controls/Presenters/ItemVirtualizer.cs

@@ -5,6 +5,7 @@ using System;
 using System.Collections;
 using System.Collections.Specialized;
 using Avalonia.Controls.Primitives;
+using Avalonia.VisualTree;
 
 namespace Avalonia.Controls.Presenters
 {
@@ -45,6 +46,11 @@ namespace Avalonia.Controls.Presenters
 
         public abstract void Arranging(Size finalSize);
 
+        public virtual bool BringIntoView(IVisual target, Rect targetRect)
+        {
+            return false;
+        }
+
         public virtual void ItemsChanged(IEnumerable items, NotifyCollectionChangedEventArgs e)
         {
             Items = items;

+ 7 - 0
src/Avalonia.Controls/Presenters/ItemsPresenter.cs

@@ -5,6 +5,7 @@ using System;
 using System.Collections.Specialized;
 using Avalonia.Controls.Primitives;
 using Avalonia.Input;
+using Avalonia.VisualTree;
 using static Avalonia.Utilities.MathUtilities;
 
 namespace Avalonia.Controls.Presenters
@@ -71,6 +72,12 @@ namespace Avalonia.Controls.Presenters
         /// <inheritdoc/>
         Size IScrollable.PageScrollSize => new Size(0, 1);
 
+        /// <inheritdoc/>
+        bool IScrollable.BringIntoView(IVisual target, Rect targetRect)
+        {
+            return _virtualizer?.BringIntoView(target, targetRect) ?? false;
+        }
+
         /// <inheritdoc/>
         protected override Size ArrangeOverride(Size finalSize)
         {

+ 7 - 0
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@@ -117,6 +117,13 @@ namespace Avalonia.Controls.Presenters
                 return false;
             }
 
+            var scrollable = Child as IScrollable;
+
+            if (scrollable?.IsLogicalScrollEnabled == true)
+            {
+                return scrollable.BringIntoView(target, targetRect);
+            }
+
             var transform = target.TransformToVisual(Child);
 
             if (transform == null)

+ 9 - 0
src/Avalonia.Controls/Primitives/IScrollable.cs

@@ -2,6 +2,7 @@
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
 using System;
+using Avalonia.VisualTree;
 
 namespace Avalonia.Controls.Primitives
 {
@@ -62,5 +63,13 @@ namespace Avalonia.Controls.Primitives
         /// Gets the size to page by, in logical units.
         /// </summary>
         Size PageScrollSize { get; }
+
+        /// <summary>
+        /// Attempts to bring a portion of the target visual into view by scrolling the content.
+        /// </summary>
+        /// <param name="target">The target visual.</param>
+        /// <param name="targetRect">The portion of the target visual to bring into view.</param>
+        /// <returns>True if the scroll offset was changed; otherwise false.</returns>
+        bool BringIntoView(IVisual target, Rect targetRect);
     }
 }

+ 6 - 1
tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests_IScrollable.cs

@@ -6,6 +6,7 @@ using System.Reactive.Linq;
 using Avalonia.Controls.Presenters;
 using Avalonia.Controls.Primitives;
 using Avalonia.Layout;
+using Avalonia.VisualTree;
 using Xunit;
 
 namespace Avalonia.Controls.UnitTests
@@ -236,7 +237,6 @@ namespace Avalonia.Controls.UnitTests
             Assert.Equal(new Rect(0, 0, 100, 100), scrollable.Bounds);
         }
 
-
         private class TestScrollable : Control, IScrollable
         {
             private Size _extent;
@@ -293,6 +293,11 @@ namespace Avalonia.Controls.UnitTests
                 }
             }
 
+            public bool BringIntoView(IVisual target, Rect targetRect)
+            {
+                throw new NotImplementedException();
+            }
+
             protected override Size MeasureOverride(Size availableSize)
             {
                 AvailableSize = availableSize;