summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs180
1 files changed, 180 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs b/Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs
new file mode 100644
index 00000000..8b5e52b5
--- /dev/null
+++ b/Xamarin.Forms.Platform.WinRT/CarouselPageRenderer.cs
@@ -0,0 +1,180 @@
+using System;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Automation;
+using Windows.UI.Xaml.Controls;
+
+#if WINDOWS_UWP
+
+namespace Xamarin.Forms.Platform.UWP
+#else
+
+namespace Xamarin.Forms.Platform.WinRT
+#endif
+{
+ public class CarouselPageRenderer : FlipView, IVisualElementRenderer
+ {
+ bool _fromUpdate;
+ bool _disposed;
+
+ BackgroundTracker<FlipView> _tracker;
+
+ public CarouselPageRenderer()
+ {
+ VirtualizingStackPanel.SetVirtualizationMode(this, VirtualizationMode.Standard);
+ ItemTemplate = (Windows.UI.Xaml.DataTemplate)Windows.UI.Xaml.Application.Current.Resources["ContainedPageTemplate"];
+ SelectionChanged += OnSelectionChanged;
+ Loaded += OnLoaded;
+ Unloaded += OnUnloaded;
+ }
+
+ public CarouselPage Element { get; private set; }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ public FrameworkElement ContainerElement
+ {
+ get { return this; }
+ }
+
+ VisualElement IVisualElementRenderer.Element
+ {
+ get { return Element; }
+ }
+
+ public event EventHandler<VisualElementChangedEventArgs> ElementChanged;
+
+ public SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint)
+ {
+ var constraint = new Windows.Foundation.Size(widthConstraint, heightConstraint);
+
+ double oldWidth = Width;
+ double oldHeight = Height;
+
+ Height = double.NaN;
+ Width = double.NaN;
+
+ Measure(constraint);
+ var result = new Size(Math.Ceiling(DesiredSize.Width), Math.Ceiling(DesiredSize.Height));
+
+ Width = oldWidth;
+ Height = oldHeight;
+
+ return new SizeRequest(result);
+ }
+
+ public void SetElement(VisualElement element)
+ {
+ var newPage = element as CarouselPage;
+ if (element != null && newPage == null)
+ throw new ArgumentException("element must be a CarouselPage");
+
+ CarouselPage oldPage = Element;
+ Element = newPage;
+
+ if (oldPage != null)
+ {
+ oldPage.SendDisappearing();
+ ((INotifyCollectionChanged)oldPage.Children).CollectionChanged -= OnChildrenChanged;
+ oldPage.PropertyChanged -= OnElementPropertyChanged;
+ }
+
+ if (newPage != null)
+ {
+ if (_tracker == null)
+ {
+ _tracker = new BackgroundTracker<FlipView>(BackgroundProperty) { Control = this };
+ }
+
+ _tracker.Element = newPage;
+
+ for (var i = 0; i < newPage.Children.Count; i++)
+ Items.Add(newPage.Children[i]);
+
+ ((INotifyCollectionChanged)newPage.Children).CollectionChanged += OnChildrenChanged;
+ newPage.PropertyChanged += OnElementPropertyChanged;
+
+ UpdateCurrentPage();
+ newPage.SendAppearing();
+ }
+
+ OnElementChanged(new ElementChangedEventArgs<CarouselPage>(oldPage, newPage));
+
+ if (!string.IsNullOrEmpty(Element?.AutomationId))
+ SetValue(AutomationProperties.AutomationIdProperty, Element.AutomationId);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposing || _disposed)
+ return;
+
+ if (_tracker != null)
+ {
+ _tracker.Dispose();
+ _tracker = null;
+ }
+
+ _disposed = true;
+ Element?.SendDisappearing();
+ SetElement(null);
+ }
+
+ protected virtual void OnElementChanged(ElementChangedEventArgs<CarouselPage> e)
+ {
+ EventHandler<VisualElementChangedEventArgs> changed = ElementChanged;
+ if (changed != null)
+ changed(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement));
+ }
+
+ protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "CurrentPage")
+ {
+ UpdateCurrentPage();
+ }
+ }
+
+ void OnChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ e.Apply(Element.Children, Items);
+ }
+
+ void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ Element?.SendAppearing();
+ }
+
+ void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (_fromUpdate)
+ return;
+
+ var page = (ContentPage)SelectedItem;
+ ContentPage currentPage = Element.CurrentPage;
+ if (currentPage == page)
+ return;
+ currentPage?.SendDisappearing();
+ Element.CurrentPage = page;
+ page?.SendAppearing();
+ }
+
+ void OnUnloaded(object sender, RoutedEventArgs e)
+ {
+ Element?.SendDisappearing();
+ }
+
+ void UpdateCurrentPage()
+ {
+ _fromUpdate = true;
+
+ SelectedItem = Element.CurrentPage;
+
+ _fromUpdate = false;
+ }
+ }
+} \ No newline at end of file