summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.WinRT/ScrollViewRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.WinRT/ScrollViewRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.WinRT/ScrollViewRenderer.cs194
1 files changed, 194 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.WinRT/ScrollViewRenderer.cs b/Xamarin.Forms.Platform.WinRT/ScrollViewRenderer.cs
new file mode 100644
index 00000000..6938a76e
--- /dev/null
+++ b/Xamarin.Forms.Platform.WinRT/ScrollViewRenderer.cs
@@ -0,0 +1,194 @@
+using System;
+using System.ComponentModel;
+using Windows.Foundation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+#if WINDOWS_UWP
+
+namespace Xamarin.Forms.Platform.UWP
+#else
+
+namespace Xamarin.Forms.Platform.WinRT
+#endif
+{
+ public class ScrollViewRenderer : ViewRenderer<ScrollView, ScrollViewer>
+ {
+ VisualElement _currentView;
+
+ public ScrollViewRenderer()
+ {
+ AutoPackage = false;
+ }
+
+ protected IScrollViewController Controller
+ {
+ get { return Element; }
+ }
+
+ public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint)
+ {
+ SizeRequest result = base.GetDesiredSize(widthConstraint, heightConstraint);
+ result.Minimum = new Size(40, 40);
+ return result;
+ }
+
+ protected override Windows.Foundation.Size ArrangeOverride(Windows.Foundation.Size finalSize)
+ {
+ if (Element == null)
+ return finalSize;
+
+ Element.IsInNativeLayout = true;
+
+ Control?.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
+
+ Element.IsInNativeLayout = false;
+
+ return finalSize;
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (Control != null)
+ {
+ Control.ViewChanged -= OnViewChanged;
+ }
+
+ base.Dispose(disposing);
+ }
+
+ protected override Windows.Foundation.Size MeasureOverride(Windows.Foundation.Size availableSize)
+ {
+ if (Element == null)
+ return new Windows.Foundation.Size(0, 0);
+
+ double width = Math.Max(0, Element.Width);
+ double height = Math.Max(0, Element.Height);
+ var result = new Windows.Foundation.Size(width, height);
+
+ Control?.Measure(result);
+
+ return result;
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<ScrollView> e)
+ {
+ base.OnElementChanged(e);
+
+ if (e.OldElement != null)
+ {
+ ((IScrollViewController)e.OldElement).ScrollToRequested -= OnScrollToRequested;
+ }
+
+ if (e.NewElement != null)
+ {
+ if (Control == null)
+ {
+ SetNativeControl(new ScrollViewer { HorizontalScrollBarVisibility = ScrollBarVisibility.Auto, VerticalScrollBarVisibility = ScrollBarVisibility.Auto });
+
+ Control.ViewChanged += OnViewChanged;
+ }
+
+ Controller.ScrollToRequested += OnScrollToRequested;
+
+ UpdateOrientation();
+
+ LoadContent();
+ }
+ }
+
+ protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ base.OnElementPropertyChanged(sender, e);
+
+ if (e.PropertyName == "Content")
+ LoadContent();
+ else if (e.PropertyName == Layout.PaddingProperty.PropertyName)
+ UpdateMargins();
+ else if (e.PropertyName == ScrollView.OrientationProperty.PropertyName)
+ UpdateOrientation();
+ }
+
+ void LoadContent()
+ {
+ if (_currentView != null)
+ {
+ _currentView.Cleanup();
+ }
+
+ _currentView = Element.Content;
+
+ IVisualElementRenderer renderer = null;
+ if (_currentView != null)
+ {
+ renderer = _currentView.GetOrCreateRenderer();
+ }
+
+ Control.Content = renderer != null ? renderer.ContainerElement : null;
+
+ UpdateMargins();
+ }
+
+ void OnScrollToRequested(object sender, ScrollToRequestedEventArgs e)
+ {
+ double x = e.ScrollX, y = e.ScrollY;
+
+ ScrollToMode mode = e.Mode;
+ if (mode == ScrollToMode.Element)
+ {
+ Point pos = Controller.GetScrollPositionForElement((VisualElement)e.Element, e.Position);
+ x = pos.X;
+ y = pos.Y;
+ mode = ScrollToMode.Position;
+ }
+
+ if (mode == ScrollToMode.Position)
+ {
+ Control.ChangeView(x, y, null, !e.ShouldAnimate);
+ }
+ }
+
+ void OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
+ {
+ Controller.SetScrolledPosition(Control.HorizontalOffset, Control.VerticalOffset);
+
+ if (!e.IsIntermediate)
+ Controller.SendScrollFinished();
+ }
+
+ void UpdateMargins()
+ {
+ var element = Control.Content as FrameworkElement;
+ if (element == null)
+ return;
+
+ switch (Element.Orientation)
+ {
+ case ScrollOrientation.Horizontal:
+ // need to add left/right margins
+ element.Margin = new Windows.UI.Xaml.Thickness(Element.Padding.Left, 0, Element.Padding.Right, 0);
+ break;
+ case ScrollOrientation.Vertical:
+ // need to add top/bottom margins
+ element.Margin = new Windows.UI.Xaml.Thickness(0, Element.Padding.Top, 0, Element.Padding.Bottom);
+ break;
+ case ScrollOrientation.Both:
+ // need to add all margins
+ element.Margin = new Windows.UI.Xaml.Thickness(Element.Padding.Left, Element.Padding.Top, Element.Padding.Right, Element.Padding.Bottom);
+ break;
+ }
+ }
+
+ void UpdateOrientation()
+ {
+ if (Element.Orientation == ScrollOrientation.Horizontal || Element.Orientation == ScrollOrientation.Both)
+ {
+ Control.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
+ }
+ else
+ {
+ Control.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
+ }
+ }
+ }
+} \ No newline at end of file