LoginSignup
2
1

More than 5 years have passed since last update.

Xamarin.Forms.GoogleMapsのPinにReadOnlyObservableCollection<Pin>をバインドする

Posted at

BehaviorBaseはnuitsjpさんのコードから拝借しました。
https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings


    public sealed class BindingPinsBehavior : BehaviorBase<Map>
    {
        void HandleNotifyCollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    var items = e.NewItems.Cast<Pin>().ToArray();
                    for (int i = 0; i < items.Length; i++)
                    {
                        _pins.Insert(e.NewStartingIndex + i, items[i]);
                    }
                    break;
                case NotifyCollectionChangedAction.Remove:
                    var oldItems = e.OldItems.Cast<Pin>().ToArray();
                    foreach (var item in oldItems)
                    {
                        _pins.Remove(item);
                    }
                    break;
                case NotifyCollectionChangedAction.Reset:
                    _pins.Clear();
                    break;
                default:
                    break;
            }
        }

        public static readonly BindableProperty ValueProperty = BindableProperty.Create("Value", typeof(ReadOnlyObservableCollection<Pin>), typeof(BindingPinsBehavior), default(ReadOnlyObservableCollection<Pin>)
                                                                                                       , defaultBindingMode: BindingMode.TwoWay
                                                                                                       , propertyChanged: (bindable, oldValue, newValue) =>
                                                                                                       {
                                                                                                           var b = bindable as BindingPinsBehavior;
                                                                                                           if (oldValue != null)
                                                                                                           {
                                                                                                               (oldValue as INotifyCollectionChanged).CollectionChanged -= b.HandleNotifyCollectionChangedEventHandler;
                                                                                                           }
                                                                                                           if (newValue != null)
                                                                                                           {
                                                                                                               (newValue as INotifyCollectionChanged).CollectionChanged += b.HandleNotifyCollectionChangedEventHandler;
                                                                                                           }
                                                                                                       });
        public ReadOnlyObservableCollection<Pin> Value
        {
            get => (ReadOnlyObservableCollection<Pin>)GetValue(ValueProperty);
            set
            {

                SetValue(ValueProperty, value);

            }
        }

        private ObservableCollection<Pin> _pins;

        protected override void OnAttachedTo(Map bindable)
        {
            base.OnAttachedTo(bindable);
            _pins = bindable.Pins as ObservableCollection<Pin>;
            if (Value != null)
            {
                (Value as INotifyCollectionChanged).CollectionChanged += HandleNotifyCollectionChangedEventHandler;
            }
        }

        protected override void OnDetachingFrom(Map bindable)
        {
            base.OnDetachingFrom(bindable);
            _pins = null;
        }
    }

    public class BehaviorBase<T> : Behavior<T> where T : BindableObject
    {
        public T AssociatedObject { get; private set; }

        internal BehaviorBase()
        {
        }

        protected override void OnAttachedTo(T bindable)
        {
            base.OnAttachedTo(bindable);
            AssociatedObject = bindable;

            if (bindable.BindingContext != null)
            {
                BindingContext = bindable.BindingContext;
            }

            bindable.BindingContextChanged += OnBindingContextChanged;
        }

        protected override void OnDetachingFrom(T bindable)
        {
            base.OnDetachingFrom(bindable);
            bindable.BindingContextChanged -= OnBindingContextChanged;
            AssociatedObject = null;
        }

        private void OnBindingContextChanged(object sender, EventArgs e)
        {
            OnBindingContextChanged();
        }

        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
            BindingContext = AssociatedObject.BindingContext;
        }
    }
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1