summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.WinRT/PickerRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.WinRT/PickerRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.WinRT/PickerRenderer.cs147
1 files changed, 147 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.WinRT/PickerRenderer.cs b/Xamarin.Forms.Platform.WinRT/PickerRenderer.cs
new file mode 100644
index 00000000..a7fcbb41
--- /dev/null
+++ b/Xamarin.Forms.Platform.WinRT/PickerRenderer.cs
@@ -0,0 +1,147 @@
+using System;
+using System.ComponentModel;
+using System.Threading.Tasks;
+using Windows.UI.Core;
+using Windows.UI.Xaml.Controls;
+
+#if WINDOWS_UWP
+
+namespace Xamarin.Forms.Platform.UWP
+#else
+
+namespace Xamarin.Forms.Platform.WinRT
+#endif
+{
+ public class PickerRenderer : ViewRenderer<Picker, FormsComboBox>
+ {
+ bool _isAnimating;
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (Control != null)
+ {
+ _isAnimating = false;
+ Control.SelectionChanged -= OnControlSelectionChanged;
+ Control.DropDownOpened -= OnDropDownOpenStateChanged;
+ Control.DropDownClosed -= OnDropDownOpenStateChanged;
+ Control.OpenAnimationCompleted -= ControlOnOpenAnimationCompleted;
+ }
+ }
+
+ base.Dispose(disposing);
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
+ {
+ if (e.NewElement != null)
+ {
+ if (Control == null)
+ {
+ SetNativeControl(new FormsComboBox());
+ Control.SelectionChanged += OnControlSelectionChanged;
+ Control.DropDownOpened += OnDropDownOpenStateChanged;
+ Control.DropDownClosed += OnDropDownOpenStateChanged;
+ Control.OpenAnimationCompleted += ControlOnOpenAnimationCompleted;
+ Control.ClosedAnimationStarted += ControlOnClosedAnimationStarted;
+ }
+
+ Control.ItemsSource = Element.Items;
+
+ UpdateTitle();
+ UpdateSelectedIndex();
+ }
+
+ base.OnElementChanged(e);
+ }
+
+ protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ base.OnElementPropertyChanged(sender, e);
+
+ if (e.PropertyName == Picker.SelectedIndexProperty.PropertyName)
+ UpdateSelectedIndex();
+ else if (e.PropertyName == Picker.TitleProperty.PropertyName)
+ UpdateTitle();
+ }
+
+ void ControlOnClosedAnimationStarted(object sender, EventArgs eventArgs)
+ {
+ if (!Control.IsFullScreen)
+ {
+ // Start refreshing while the control's closing animation runs;
+ // OnDropDownOpenStateChanged will take care of stopping the refresh
+ StartAnimationRefresh();
+ }
+ }
+
+ void ControlOnOpenAnimationCompleted(object sender, EventArgs eventArgs)
+ {
+ _isAnimating = false;
+ if (!Control.IsFullScreen)
+ {
+ // Force a final redraw after the closing animation has completed
+ Element?.InvalidateMeasure(InvalidationTrigger.MeasureChanged);
+ }
+ }
+
+ void OnControlSelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (Element != null)
+ Element.SelectedIndex = Control.SelectedIndex;
+ }
+
+ void OnDropDownOpenStateChanged(object sender, object o)
+ {
+ if (Control.IsDropDownOpen)
+ {
+ if (Control.IsOpeningAnimated && !Control.IsFullScreen)
+ {
+ // Start running the animation refresh;
+ // ControlOnOpenAnimationCompleted will take care of stopping it
+ StartAnimationRefresh();
+ }
+ else
+ {
+ Element?.InvalidateMeasure(InvalidationTrigger.MeasureChanged);
+ }
+ }
+ else
+ {
+ // The ComboBox is now closed; if we were animating the closure, stop
+ _isAnimating = false;
+ // and force the final redraw
+ Element?.InvalidateMeasure(InvalidationTrigger.MeasureChanged);
+ }
+ }
+
+ /// <summary>
+ /// Forces redraw of the control during opening/closing animations to provide
+ /// a smoother sliding animation for the surrounding controls
+ /// Only applies on the phone and only when there are fewer than 6 items in the picker
+ /// </summary>
+ void StartAnimationRefresh()
+ {
+ _isAnimating = true;
+ Task.Factory.StartNew(async () =>
+ {
+ while (_isAnimating)
+ {
+ await Task.Delay(16);
+ await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Element?.InvalidateMeasure(InvalidationTrigger.MeasureChanged));
+ }
+ });
+ }
+
+ void UpdateSelectedIndex()
+ {
+ Control.SelectedIndex = Element.SelectedIndex;
+ }
+
+ void UpdateTitle()
+ {
+ Control.Header = Element.Title;
+ }
+ }
+} \ No newline at end of file