var index1 = indexes[0];
var index2 = indexes[1];
- if (index1 > -1 && index2 > -1 && index1 < observableCollection.Count &&
- index2 < observableCollection.Count && index1 < index2)
+ if (index1 > -1 && index2 < observableCollection.Count && index1 <= index2)
{
if (_withIndex)
{
- observableCollection.TestRemoveWithListAndIndex(index1, index2 - index1);
+ observableCollection.TestRemoveWithListAndIndex(index1, (index2 - index1) + 1);
}
else
{
- observableCollection.TestRemoveWithList(index1, index2 - index1);
+ observableCollection.TestRemoveWithList(index1, (index2 - index1) + 1);
}
}
}
var index1 = indexes[0];
var index2 = indexes[1];
- if (index1 > -1 && index2 > -1 && index1 < observableCollection.Count &&
- index2 < observableCollection.Count && index1 < index2)
+ if (index1 > -1 && index2 < observableCollection.Count && index1 <= index2)
{
var newItems = new List<CollectionViewGalleryTestItem>();
if (_withIndex)
{
- observableCollection.TestReplaceWithListAndIndex(index1, index2 - index1, newItems);
+ observableCollection.TestReplaceWithListAndIndex(index1, index2 - index1 + 1, newItems);
}
else
{
- observableCollection.TestReplaceWithList(index1, index2 - index1, newItems);
+ observableCollection.TestReplaceWithList(index1, index2 - index1 + 1, newItems);
}
}
}
--- /dev/null
+namespace Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries
+{
+ internal class ObservableCollectionResetGallery : ContentPage
+ {
+ public ObservableCollectionResetGallery()
+ {
+ var layout = new Grid
+ {
+ RowDefinitions = new RowDefinitionCollection
+ {
+ new RowDefinition { Height = GridLength.Auto },
+ new RowDefinition { Height = GridLength.Auto },
+ new RowDefinition { Height = GridLength.Star }
+ }
+ };
+
+ var itemsLayout = new GridItemsLayout(3, ItemsLayoutOrientation.Vertical) as IItemsLayout;
+
+ var itemTemplate = ExampleTemplates.PhotoTemplate();
+
+ var collectionView = new CollectionView { ItemsLayout = itemsLayout, ItemTemplate = itemTemplate };
+
+ var generator = new ItemsSourceGenerator(collectionView, 100, ItemsSourceType.MultiTestObservableCollection);
+
+ layout.Children.Add(generator);
+
+ var resetter = new Resetter(collectionView);
+ layout.Children.Add(resetter);
+ Grid.SetRow(resetter, 1);
+
+ layout.Children.Add(collectionView);
+ Grid.SetRow(collectionView, 2);
+
+ Content = layout;
+
+ generator.GenerateItems();
+ }
+ }
+}
\ No newline at end of file
generator.GenerateItems();
}
}
-
- internal class ObservableCollectionResetGallery : ContentPage
- {
- public ObservableCollectionResetGallery()
- {
- var layout = new Grid
- {
- RowDefinitions = new RowDefinitionCollection
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Star }
- }
- };
-
- var itemsLayout = new GridItemsLayout(3, ItemsLayoutOrientation.Vertical) as IItemsLayout;
-
- var itemTemplate = ExampleTemplates.PhotoTemplate();
-
- var collectionView = new CollectionView { ItemsLayout = itemsLayout, ItemTemplate = itemTemplate };
-
- var generator = new ItemsSourceGenerator(collectionView, 100, ItemsSourceType.MultiTestObservableCollection);
-
- layout.Children.Add(generator);
-
- var resetter = new Resetter(collectionView);
- layout.Children.Add(resetter);
- Grid.SetRow(resetter, 1);
-
- layout.Children.Add(collectionView);
- Grid.SetRow(collectionView, 2);
-
- Content = layout;
-
- generator.GenerateItems();
- }
- }
}
\ No newline at end of file
((INotifyCollectionChanged)itemSource).CollectionChanged += CollectionChanged;
}
+ public int Count => _itemsSource.Count;
+
+ public object this[int index] => _itemsSource[index];
+
void CollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
switch (args.Action)
void Move(NotifyCollectionChangedEventArgs args)
{
- var oldPath = NSIndexPath.Create(0, args.OldStartingIndex);
- var newPath = NSIndexPath.Create(0, args.NewStartingIndex);
+ var count = args.NewItems.Count;
+
+ if (count == 1)
+ {
+ // For a single item, we can use MoveItem and get the animation
+ var oldPath = NSIndexPath.Create(0, args.OldStartingIndex);
+ var newPath = NSIndexPath.Create(0, args.NewStartingIndex);
+
+ _collectionView.MoveItem(oldPath, newPath);
+ return;
+ }
- _collectionView.MoveItem(oldPath, newPath);
+ var start = Math.Min(args.OldStartingIndex, args.NewStartingIndex);
+ var end = Math.Max(args.OldStartingIndex, args.NewStartingIndex) + count;
+ _collectionView.ReloadItems(CreateIndexesFrom(start, end));
}
private void Replace(NotifyCollectionChangedEventArgs args)
{
- var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]);
- var count = args.NewItems.Count;
+ var newCount = args.NewItems.Count;
- _collectionView.ReloadItems(CreateIndexesFrom(startIndex, count));
+ if (newCount == args.OldItems.Count)
+ {
+ var startIndex = args.NewStartingIndex > -1 ? args.NewStartingIndex : _itemsSource.IndexOf(args.NewItems[0]);
+
+ // We are replacing one set of items with a set of equal size; we can do a simple item range update
+ _collectionView.ReloadItems(CreateIndexesFrom(startIndex, newCount));
+ return;
+ }
+
+ // The original and replacement sets are of unequal size; this means that everything currently in view will
+ // have to be updated. So we just have to use ReloadData and let the UICollectionView update everything
+ _collectionView.ReloadData();
}
static NSIndexPath[] CreateIndexesFrom(int startIndex, int count)
void Remove(NotifyCollectionChangedEventArgs args)
{
- var startIndex = args.OldStartingIndex > -1 ? args.OldStartingIndex : _itemsSource.IndexOf(args.OldItems[0]);
- var count = args.OldItems.Count;
+ var startIndex = args.OldStartingIndex;
+
+ if (startIndex < 0)
+ {
+ // INCC implementation isn't giving us enough information to know where the removed items were in the
+ // collection. So the best we can do is a ReloadData()
+ _collectionView.ReloadData();
+ return;
+ }
+ // If we have a start index, we can be more clever about removing the item(s) (and get the nifty animations)
+ var count = args.OldItems.Count;
_collectionView.DeleteItems(CreateIndexesFrom(startIndex, count));
}
-
- public int Count => _itemsSource.Count;
-
- public object this[int index] => _itemsSource[index];
}
}
\ No newline at end of file