简体   繁体   中英

ObservableCollection.CollectionChanged not being called

Ok, I have search and nothing I see gives me a solution so here I go. I have a public ObservableCollection<Photo> Items { get; set;} public ObservableCollection<Photo> Items { get; set;} that doesn't update the UI in MonoDroid everything on Monotouch works fine.

Upon further review: Remove and Add both aren't not refreshing the collection. I have to rotate the device to see the changes. (only on Android)

my view is bound like this:

this.BindingContext = _viewModel;

        var activityIndicator = new BrandActivityIndicator{
            VerticalOptions = LayoutOptions.Start,
            HorizontalOptions = LayoutOptions.Center
        };

        activityIndicator.SetBinding<PhotosViewModel>(BrandActivityIndicator.IsVisibleProperty, vm => vm.IsBusy);
        activityIndicator.SetBinding<PhotosViewModel>(BrandActivityIndicator.IsRunningProperty, vm => vm.IsBusy);

        this.Padding = new Thickness(10, 5, 10, 0);
        this.HorizontalOptions = LayoutOptions.FillAndExpand;
        this.VerticalOptions = LayoutOptions.FillAndExpand;

        _gridView = new GridView
        {      
            RowSpacing = 15,
            ColumnSpacing = 15,        
            ItemWidth = 85,        
            ItemHeight = 85,       
            HorizontalOptions = LayoutOptions.FillAndExpand,       
            VerticalOptions = LayoutOptions.FillAndExpand,     
            ItemTemplate = new DataTemplate(typeof(ImagesViewCell))
        };     

        _gridView.SetBinding<PhotosViewModel> (GridView.ItemsSourceProperty, vm => vm.Items); 
        _gridView.SetBinding<PhotosViewModel> (GridView.IsVisibleProperty, vm => vm.NotBusy);        

        var layout = new StackLayout
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                Children = {
                    activityIndicator,
                    _gridView
                }
            };

        this.Content = layout;

GridView is but a ContentView

public class GridView : ContentView
{
    public GridView()
    {
        SelectionEnabled = true;

    }

    public static readonly BindableProperty ItemsSourceProperty = 
        BindableProperty.Create<GridView,IEnumerable>(p => p.ItemsSource, null);
}

the viewModel is standard

public class PhotosViewModel : BaseViewModel, IBadge
    {
        private readonly TaskScheduler _scheduler = TaskScheduler.FromCurrentSynchronizationContext();

        public ObservableCollection<Photo> Items { get; set;}
        public PhotosViewModel()
        {
            Items = new ObservableCollection<Photo>();

        }
}

I tried attaching a Items.CollectionChanged += notify and it wasn't called. At this moment I am out ideas.

This is a bit of a guess, bit it may be possible that there is a bug in the Android implementation of ContentView . You are trying to bind your ObsevableCollection to a binding that is declared as IEnumerable . This shouldn't matter, but maybe there is a bug where the android implementation detects IEnumerable but doesn't test its underlying type to see if it is also INotifyCollectionChanged . Try changing it from IEnumerable to the concrete type and see if that works. As I said, this is a guess based on similar issues I found in the WPF world.

I found the answer, I created a custom renderer and bound the property using InotifyCollectionChanged .

if (newElement != null)
            {
                newElement.PropertyChanging += ElementPropertyChanging;
                newElement.PropertyChanged += ElementPropertyChanged;
                if (newElement.ItemsSource is INotifyCollectionChanged)
                    (newElement.ItemsSource as INotifyCollectionChanged).CollectionChanged += DataCollectionChanged;
            }


protected virtual void ElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ItemsSource")
            {
                if (Element.ItemsSource is INotifyCollectionChanged)
                    (Element.ItemsSource as INotifyCollectionChanged).CollectionChanged += DataCollectionChanged;

                context.RunOnUiThread (() => UpdateFromCollectionChange ());
            }
        }

for whatever reason out there the ObservableCollection doesn't fire the collectionChanged event on Android using Xamarin.forms without a renderer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM