typeof(ContextPopup), defaultValue: _priorities);
public static readonly BindableProperty SelectedIndexProperty = BindableProperty.Create(nameof(SelectedIndex), typeof(int), typeof(ContextPopup), defaultValue: -1,
- propertyChanged: OnSelectedIndexChanged);
+ propertyChanged: OnSelectedIndexChanged, coerceValue: CoerceSelectedIndex);
public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create(nameof(SelectedItem), typeof(object), typeof(ContextPopup), null,
propertyChanged: OnSelectedItemChanged);
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
- var addedItems = e.NewItems.OfType<ContextPopupItem>();
- _contextPopup.AddItems(addedItems);
- foreach (var item in addedItems)
- {
- item.PropertyChanged += ContextPopupItemPropertyChanged;
- }
+ AddItems(e);
break;
case NotifyCollectionChangedAction.Remove:
- _contextPopup.RemoveItems(e.OldItems.OfType<ContextPopupItem>());
+ RemoveItems(e);
break;
- case NotifyCollectionChangedAction.Reset:
- _contextPopup.ClearItems();
- SelectedIndex = -1;
+ default: // Move, replace, reset
+ ResetItems();
break;
+ }
- default: //Clear and add again for anything else such as Move
- _contextPopup.ClearItems();
- _contextPopup.AddItems(_items);
- SelectedIndex = -1;
- break;
+ SelectedIndex = SelectedIndex.Clamp(-1, Items.Count - 1);
+ UpdateSelectedItem();
+ }
+
+ void ResetItems()
+ {
+ _contextPopup.ClearItems();
+ if (ItemsSource != null)
+ {
+ if (_items.Count != 0)
+ _items.Clear();
+ else
+ {
+ foreach (var item in ItemsSource)
+ _items.Add(ConvertObjectToContextPopupItem(item));
+ }
+ }
+ }
+
+ void RemoveItems(NotifyCollectionChangedEventArgs e)
+ {
+ IList<ContextPopupItem> items = new List<ContextPopupItem>();
+
+ foreach (object oldItem in e.OldItems)
+ {
+ var item = ConvertObjectToContextPopupItem(oldItem);
+ item.PropertyChanged -= ContextPopupItemPropertyChanged;
+ items.Add(item);
+ }
+
+ _contextPopup.RemoveItems(items);
+ }
+
+ void AddItems(NotifyCollectionChangedEventArgs e)
+ {
+ IList<ContextPopupItem> items = new List<ContextPopupItem>();
+
+ foreach (object newItem in e.NewItems)
+ {
+ var item = ConvertObjectToContextPopupItem(newItem);
+ item.PropertyChanged += ContextPopupItemPropertyChanged;
+ items.Add(item);
}
+
+ _contextPopup.AddItems(items);
+ }
+
+ ContextPopupItem ConvertObjectToContextPopupItem(object item)
+ {
+ if (item is ContextPopupItem)
+ return item as ContextPopupItem;
+ else
+ return new ContextPopupItem(item.ToString());
}
void ContextPopupItemPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
contextPopup.SelectedIndexChanged?.Invoke(contextPopup, EventArgs.Empty);
}
+ static object CoerceSelectedIndex(BindableObject bindable, object value)
+ {
+ var contextPopup = (ContextPopup)bindable;
+ return contextPopup.Items == null ? -1 : ((int)value).Clamp(-1, contextPopup.Items.Count - 1);
+ }
+
void UpdateSelectedItem()
{
if (SelectedIndex == -1)
if (newValue != null)
{
- _items.Clear();
- foreach (var item in newValue)
- {
- _items.Add(item as ContextPopupItem);
- }
+ ResetItems();
}
else
{
}
}
}
+
+ internal static class NumericExtensions
+ {
+ public static int Clamp(this int self, int min, int max)
+ {
+ return Math.Min(max, Math.Max(self, min));
+ }
+ }
}
\ No newline at end of file