From: jh5.cho Date: Mon, 27 Mar 2017 13:54:46 +0000 (+0900) Subject: [DropdownList] Fix Updating SelectedItem Issue X-Git-Tag: accepted/tizen/unified/20170421.115620~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F16%2F121316%2F10;p=platform%2Fcore%2Fcsapi%2Fxamarin-forms-extension.git [DropdownList] Fix Updating SelectedItem Issue - Update setting SelectedItem (as item object itself, not as string text) - Fix Updating Text when SelectedItem is set when it launches - Update items when member values in ItemsSource is changed Change-Id: I8c2cea184214478fdaadf55eb1c10ba8c817fc30 --- diff --git a/Tizen.Xamarin.Forms.Extension.Renderer/DropdownListRenderer.cs b/Tizen.Xamarin.Forms.Extension.Renderer/DropdownListRenderer.cs index 94ecf0c..a57e9be 100755 --- a/Tizen.Xamarin.Forms.Extension.Renderer/DropdownListRenderer.cs +++ b/Tizen.Xamarin.Forms.Extension.Renderer/DropdownListRenderer.cs @@ -1,3 +1,4 @@ +using ElmSharp; using System; using System.Collections; using System.Collections.Generic; @@ -5,28 +6,24 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; +using System.Reflection; using Tizen.Xamarin.Forms.Extension; using Tizen.Xamarin.Forms.Extension.Renderer; using Xamarin.Forms.Platform.Tizen; -using EHoversel = ElmSharp.Hoversel; using TForms = Xamarin.Forms.Platform.Tizen.Forms; [assembly: ExportRenderer(typeof(DropdownList), typeof(DropdownListRenderer))] namespace Tizen.Xamarin.Forms.Extension.Renderer { - public class DropdownListRenderer : ViewRenderer + public class DropdownListRenderer : ViewRenderer { - Dictionary _items = new Dictionary(); - - public DropdownListRenderer() - { - } + Dictionary _items = new Dictionary(); protected override void OnElementChanged(ElementChangedEventArgs e) { if (Control == null) { - var dropdownList = new EHoversel(TForms.Context.MainWindow); + var dropdownList = new Hoversel(TForms.Context.MainWindow); SetNativeControl(dropdownList); } if (e.OldElement != null) @@ -43,16 +40,16 @@ namespace Tizen.Xamarin.Forms.Extension.Renderer Control.HoverParent = Platform.GetRenderer(Element.Parent)?.NativeView; - ClearItems(); AddItems(e.NewElement.InternalItems); UpdateIsHorizontal(); UpdateIsExpanded(); + UpdateText(); } base.OnElementChanged(e); } - void ItemSelectedEventHandler(object sender, ElmSharp.HoverselItemEventArgs e) + void ItemSelectedEventHandler(object sender, HoverselItemEventArgs e) { Element.SelectedItem = _items[e.Item]; } @@ -62,6 +59,49 @@ namespace Tizen.Xamarin.Forms.Extension.Renderer Element.IsExpanded = false; } + bool IsPrimitive() + { + string displayMemberPath = Element.DisplayMemberPath; + if (string.IsNullOrEmpty(displayMemberPath) || string.IsNullOrWhiteSpace(displayMemberPath)) + { + return true; + } + object itemsSourceObj = Element.ItemsSource.OfType().FirstOrDefault(); + var typeInfo = itemsSourceObj.GetType().GetTypeInfo(); + if (typeInfo.IsVisible || typeInfo.IsPrimitive || typeInfo.IsValueType) + { + return true; + } + return false; + } + + string GetDisplayMember(object item) + { + if(IsPrimitive()) + { + return item.ToString(); + } + + var propertyPathParts = Element.DisplayMemberPath.Split('.'); + object propertyValue = item; + foreach (var propertyPathPart in propertyPathParts) + { + var propInfo = propertyValue.GetType().GetTypeInfo().GetDeclaredProperty(propertyPathPart); + if (propInfo == null) + { + // No Property was found + return item.ToString(); + } + propertyValue = propInfo.GetValue(propertyValue); + } + if (propertyValue == null) + { + // No Property was found + return item.ToString(); + } + return propertyValue.ToString(); + } + protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == DropdownList.IsHorizontalProperty.PropertyName) @@ -72,6 +112,10 @@ namespace Tizen.Xamarin.Forms.Extension.Renderer { UpdateIsExpanded(); } + else if (e.PropertyName == DropdownList.DisplayMemberPathProperty.PropertyName) + { + UpdateElementItems(_items); + } else if (e.PropertyName == DropdownList.SelectedItemProperty.PropertyName) { UpdateText(); @@ -98,7 +142,7 @@ namespace Tizen.Xamarin.Forms.Extension.Renderer void UpdateText() { - Control.Text = Element.SelectedItem != null ? Element.SelectedItem.ToString() : string.Empty; + Control.Text = Element.SelectedItem != null ? GetDisplayMember(Element.SelectedItem) : string.Empty; } void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) @@ -121,8 +165,30 @@ namespace Tizen.Xamarin.Forms.Extension.Renderer { foreach (object item in items) { - _items.Add(Control.AddItem(item.ToString()), item); + if (item is INotifyPropertyChanged) + { + ((INotifyPropertyChanged)item).PropertyChanged -= OnItemPropertyChanged; + ((INotifyPropertyChanged)item).PropertyChanged += OnItemPropertyChanged; + } + _items.Add(Control.AddItem(GetDisplayMember(item)), item); + } + } + + private void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (Element.DisplayMemberPath == e.PropertyName) + { + UpdateElementItems(_items.Where(p => p.Value == sender)); + } + } + + void UpdateElementItems(IEnumerable> items) + { + foreach (var target in items) + { + target.Key.SetPartText("default", GetDisplayMember(target.Value)); } + UpdateText(); } void RemoveItems(IEnumerable items) @@ -130,9 +196,11 @@ namespace Tizen.Xamarin.Forms.Extension.Renderer foreach (object item in items) { var target = _items.Where(d => d.Value == item).ToList(); - if (target.Count == 1) + if (target.Count == 1 && (target[0].Value == Element.SelectedItem)) { Element.SelectedItem = null; + if (item is INotifyPropertyChanged) + ((INotifyPropertyChanged)item).PropertyChanged -= OnItemPropertyChanged; } _items.Remove(target[0].Key); target[0].Key.Delete(); diff --git a/Tizen.Xamarin.Forms.Extension/DropdownList.cs b/Tizen.Xamarin.Forms.Extension/DropdownList.cs old mode 100644 new mode 100755 index 2571ea2..784cd4a --- a/Tizen.Xamarin.Forms.Extension/DropdownList.cs +++ b/Tizen.Xamarin.Forms.Extension/DropdownList.cs @@ -2,7 +2,6 @@ using System; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Specialized; -using System.Reflection; using Xamarin.Forms; namespace Tizen.Xamarin.Forms.Extension @@ -53,7 +52,7 @@ namespace Tizen.Xamarin.Forms.Extension /// /// BindableProperty. Identifies the DisplayMemberPath bindable property. /// - public static readonly BindableProperty DisplayMemberPathProperty = BindableProperty.Create("DisplayMemberPath", typeof(string), typeof(DropdownList), default(string), propertyChanged: OnDisplayMemberPathChanged); + public static readonly BindableProperty DisplayMemberPathProperty = BindableProperty.Create("DisplayMemberPath", typeof(string), typeof(DropdownList), default(string)); /// /// Occurs when an item in the DropdownList is selected. @@ -65,10 +64,6 @@ namespace Tizen.Xamarin.Forms.Extension ObservableCollection _items = new ObservableCollection(); - public DropdownList() - { - } - /// /// Gets or sets the currently selected item from the DropdownList.ItemsSource. /// @@ -163,7 +158,7 @@ namespace Tizen.Xamarin.Forms.Extension void AddItems(NotifyCollectionChangedEventArgs e) { foreach (object newItem in e.NewItems) - _items.Add(GetDisplayMember(newItem)); + _items.Add(newItem); } void RemoveItems(NotifyCollectionChangedEventArgs e) @@ -180,20 +175,7 @@ namespace Tizen.Xamarin.Forms.Extension _items.Clear(); foreach (object item in ItemsSource) - _items.Add(GetDisplayMember(item)); - } - - object GetDisplayMember(object item) - { - if (string.IsNullOrEmpty(DisplayMemberPath) || string.IsNullOrWhiteSpace(DisplayMemberPath)) - return item.ToString(); - - PropertyInfo prop = item.GetType().GetRuntimeProperty(DisplayMemberPath); - - if (prop == null) - return item.ToString(); - - return prop.GetValue(item); + _items.Add(item); } static object OnCoerceSelectedItem(BindableObject bindable, object value) @@ -207,15 +189,8 @@ namespace Tizen.Xamarin.Forms.Extension static void OnSelectedItemChanged(BindableObject bindable, object oldValue, object newValue) { - var dropdownList = bindable as DropdownList; - if (oldValue != newValue) - dropdownList.ItemSelected?.Invoke(bindable as DropdownList, new SelectedItemChangedEventArgs(newValue)); - } - - static void OnDisplayMemberPathChanged(BindableObject bindable, object oldValue, object newValue) - { - var dropdownList = bindable as DropdownList; - dropdownList.ResetItems(); + var dropdownList = (DropdownList)bindable; + dropdownList.ItemSelected?.Invoke(bindable, new SelectedItemChangedEventArgs(newValue)); } } -} \ No newline at end of file +}