summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.WP8/PickerRenderer.cs
diff options
context:
space:
mode:
authorJason Smith <jason.smith@xamarin.com>2016-03-22 13:02:25 -0700
committerJason Smith <jason.smith@xamarin.com>2016-03-22 16:13:41 -0700
commit17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch)
treeb5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Platform.WP8/PickerRenderer.cs
downloadxamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz
xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2
xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip
Initial import
Diffstat (limited to 'Xamarin.Forms.Platform.WP8/PickerRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.WP8/PickerRenderer.cs256
1 files changed, 256 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.WP8/PickerRenderer.cs b/Xamarin.Forms.Platform.WP8/PickerRenderer.cs
new file mode 100644
index 00000000..f9cd2d81
--- /dev/null
+++ b/Xamarin.Forms.Platform.WP8/PickerRenderer.cs
@@ -0,0 +1,256 @@
+using System;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Reflection;
+using System.Windows;
+using System.Windows.Controls;
+using Microsoft.Phone.Controls;
+
+namespace Xamarin.Forms.Platform.WinPhone
+{
+ public class PickerRenderer : ViewRenderer<Picker, FrameworkElement>
+ {
+ bool _isChanging;
+
+ FormsListPicker _listPicker;
+
+ protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
+ {
+ _listPicker = new FormsListPicker();
+
+ UpdateAlignment();
+ UpdateIsEnabled();
+
+ base.OnElementChanged(e);
+
+ if (e.OldElement != null)
+ ((ObservableList<string>)Element.Items).CollectionChanged -= ItemsCollectionChanged;
+
+ ((ObservableList<string>)Element.Items).CollectionChanged += ItemsCollectionChanged;
+
+ _listPicker.ItemTemplate = (System.Windows.DataTemplate)System.Windows.Application.Current.Resources["PickerItemTemplate"];
+ _listPicker.FullModeItemTemplate = (System.Windows.DataTemplate)System.Windows.Application.Current.Resources["PickerFullItemTemplate"];
+ _listPicker.ExpansionMode = ExpansionMode.FullScreenOnly;
+ _listPicker.Items.Add(new ItemViewModel(" ") { MaxHeight = 0 });
+
+ _listPicker.ListPickerModeChanged += ListPickerModeChanged;
+
+ var grid = new System.Windows.Controls.Grid { Children = { _listPicker }, MaxWidth = Device.Info.PixelScreenSize.Width };
+ SetNativeControl(grid);
+
+ UpdatePicker();
+ _listPicker.SelectionChanged += PickerSelectionChanged;
+ }
+
+ protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ base.OnElementPropertyChanged(sender, e);
+ if (e.PropertyName == Picker.TitleProperty.PropertyName)
+ _listPicker.FullModeHeader = Element.Title;
+
+ if (e.PropertyName == VisualElement.IsEnabledProperty.PropertyName)
+ UpdateIsEnabled();
+
+ if (e.PropertyName == Picker.SelectedIndexProperty.PropertyName)
+ {
+ if (Element.SelectedIndex >= 0 && Element.SelectedIndex < Element.Items.Count)
+ _listPicker.SelectedIndex = Element.SelectedIndex + 1;
+ }
+
+ if (e.PropertyName == View.HorizontalOptionsProperty.PropertyName)
+ UpdateAlignment();
+ }
+
+ protected override void OnGotFocus(object sender, RoutedEventArgs args)
+ {
+ // Do nothing. ListPickerModeChanged is handling the IsFocusProperty setter
+ // Required because FrameworkElement.GotFocus and FrameworkElement.LostFocus () are fired by ListPicker.Open ()
+ }
+
+ protected override void OnLostFocus(object sender, RoutedEventArgs args)
+ {
+ // Do nothing. ListPickerModeChanged is handling the IsFocusProperty setter
+ // Required because FrameworkElement.GotFocus and FrameworkElement.LostFocus () are fired by ListPicker.Open ()
+ }
+
+ protected override void UpdateNativeWidget()
+ {
+ base.UpdateNativeWidget();
+ UpdateIsEnabled();
+ }
+
+ internal override void OnModelFocusChangeRequested(object sender, VisualElement.FocusRequestArgs args)
+ {
+ if (Control == null)
+ return;
+
+ if (args.Focus)
+ args.Result = OpenPickerPage();
+ else
+ {
+ args.Result = ClosePickerPage();
+ UnfocusControl(_listPicker);
+ }
+ }
+
+ bool ClosePickerPage()
+ {
+ FieldInfo pickerPageField = typeof(ListPicker).GetField("_listPickerPage", BindingFlags.NonPublic | BindingFlags.Instance);
+ var pickerPage = pickerPageField.GetValue(Control) as ListPickerPage;
+ typeof(ListPickerPage).InvokeMember("ClosePickerPage", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, Type.DefaultBinder, pickerPage, null);
+
+ return true;
+ }
+
+ void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ UpdateItems();
+ }
+
+ void ListPickerModeChanged(object sender, DependencyPropertyChangedEventArgs e)
+ {
+ if (e.OldValue == null || e.NewValue == null)
+ return;
+
+ var oldVal = (ListPickerMode)e.OldValue;
+ var newVal = (ListPickerMode)e.NewValue;
+
+ if (oldVal == ListPickerMode.Normal && newVal == ListPickerMode.Full)
+ {
+ // Picker Page is now showing
+ ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
+ }
+ else if (oldVal == ListPickerMode.Full && newVal == ListPickerMode.Normal)
+ {
+ // PickerPage is now dismissed
+ ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
+ }
+ }
+
+ bool OpenPickerPage()
+ {
+ bool result = _listPicker.Open();
+
+ if (result)
+ return true;
+
+ return false;
+ }
+
+ void PickerSelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (_isChanging)
+ return;
+
+ var picker = (ListPicker)sender;
+
+ // initializing picker
+ if (picker.SelectedIndex == -1)
+ return;
+
+ int elementSelectedIndex = picker.SelectedIndex - 1;
+ ((IElementController)Element).SetValueFromRenderer(Picker.SelectedIndexProperty, elementSelectedIndex);
+ }
+
+ void UpdateAlignment()
+ {
+ if (Element.HorizontalOptions.Alignment != LayoutAlignment.Fill)
+ _listPicker.HorizontalAlignment = HorizontalAlignment.Left;
+ }
+
+ void UpdateIsEnabled()
+ {
+ if (_listPicker != null)
+ _listPicker.IsEnabled = Element.IsEnabled;
+ }
+
+ void UpdateItems()
+ {
+ // supress notification of non-user generated events (e.g. adding\syncing list values)
+ _isChanging = true;
+ FormsListPicker picker = _listPicker;
+ // add/remove slots from control to match element
+ while (picker.Items.Count < Element.Items.Count + 1)
+ picker.Items.Add(new ItemViewModel(string.Empty));
+
+ while (picker.Items.Count > Element.Items.Count + 1)
+ picker.Items.RemoveAt(picker.Items.Count - 1);
+
+ // update all control values to match element values
+ for (var i = 0; i < Element.Items.Count; i++)
+ {
+ var item = (ItemViewModel)picker.Items[i + 1];
+ if (item.Data == Element.Items[i])
+ continue;
+
+ item.Data = Element.Items[i];
+ }
+
+ picker.SelectedIndex = Element.SelectedIndex + 1;
+
+ _isChanging = false;
+ }
+
+ void UpdatePicker()
+ {
+ _listPicker.FullModeHeader = Element.Title;
+ UpdateItems();
+ _listPicker.SelectedIndex = Element.SelectedIndex + 1;
+ }
+
+ class ItemViewModel : INotifyPropertyChanged
+ {
+ string _data;
+ int _maxHeight;
+ float _opacity;
+
+ public ItemViewModel(string item)
+ {
+ _opacity = 1;
+ _data = item;
+ _maxHeight = int.MaxValue;
+ }
+
+ public string Data
+ {
+ get { return _data; }
+ set
+ {
+ if (value == _data)
+ return;
+
+ _data = value;
+ PropertyChanged(this, new PropertyChangedEventArgs("Data"));
+ }
+ }
+
+ public int MaxHeight
+ {
+ get { return _maxHeight; }
+ set
+ {
+ if (value == _maxHeight)
+ return;
+
+ _maxHeight = value;
+ PropertyChanged(this, new PropertyChangedEventArgs("MaxHeight"));
+ }
+ }
+
+ public float Opacity
+ {
+ get { return _opacity; }
+ set
+ {
+ if (value == _opacity)
+ return;
+
+ _opacity = value;
+ PropertyChanged(this, new PropertyChangedEventArgs("Opacity"));
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged = delegate { };
+ }
+ }
+} \ No newline at end of file