summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Core/NotifyCollectionChangedEventArgsExtensions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Core/NotifyCollectionChangedEventArgsExtensions.cs')
-rw-r--r--Xamarin.Forms.Core/NotifyCollectionChangedEventArgsExtensions.cs105
1 files changed, 105 insertions, 0 deletions
diff --git a/Xamarin.Forms.Core/NotifyCollectionChangedEventArgsExtensions.cs b/Xamarin.Forms.Core/NotifyCollectionChangedEventArgsExtensions.cs
new file mode 100644
index 00000000..2ddf92c4
--- /dev/null
+++ b/Xamarin.Forms.Core/NotifyCollectionChangedEventArgsExtensions.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace Xamarin.Forms
+{
+ internal static class NotifyCollectionChangedEventArgsExtensions
+ {
+ public static void Apply<TFrom>(this NotifyCollectionChangedEventArgs self, IList<TFrom> from, IList<object> to)
+ {
+ self.Apply((o, i, b) => to.Insert(i, o), (o, i) => to.RemoveAt(i), () =>
+ {
+ to.Clear();
+ for (var i = 0; i < from.Count; i++)
+ to.Add(from[i]);
+ });
+ }
+
+ public static NotifyCollectionChangedAction Apply(this NotifyCollectionChangedEventArgs self, Action<object, int, bool> insert, Action<object, int> removeAt, Action reset)
+ {
+ if (self == null)
+ throw new ArgumentNullException("self");
+ if (reset == null)
+ throw new ArgumentNullException("reset");
+ if (insert == null)
+ throw new ArgumentNullException("insert");
+ if (removeAt == null)
+ throw new ArgumentNullException("removeAt");
+
+ switch (self.Action)
+ {
+ case NotifyCollectionChangedAction.Add:
+ if (self.NewStartingIndex < 0)
+ goto case NotifyCollectionChangedAction.Reset;
+
+ for (var i = 0; i < self.NewItems.Count; i++)
+ insert(self.NewItems[i], i + self.NewStartingIndex, true);
+
+ break;
+
+ case NotifyCollectionChangedAction.Move:
+ if (self.NewStartingIndex < 0 || self.OldStartingIndex < 0)
+ goto case NotifyCollectionChangedAction.Reset;
+
+ for (var i = 0; i < self.OldItems.Count; i++)
+ removeAt(self.OldItems[i], self.OldStartingIndex);
+
+ int insertIndex = self.NewStartingIndex;
+ if (self.OldStartingIndex < self.NewStartingIndex)
+ insertIndex -= self.OldItems.Count - 1;
+
+ for (var i = 0; i < self.OldItems.Count; i++)
+ insert(self.OldItems[i], insertIndex + i, false);
+
+ break;
+
+ case NotifyCollectionChangedAction.Remove:
+ if (self.OldStartingIndex < 0)
+ goto case NotifyCollectionChangedAction.Reset;
+
+ for (var i = 0; i < self.OldItems.Count; i++)
+ removeAt(self.OldItems[i], self.OldStartingIndex);
+ break;
+
+ case NotifyCollectionChangedAction.Replace:
+ if (self.OldStartingIndex < 0)
+ goto case NotifyCollectionChangedAction.Reset;
+
+ for (var i = 0; i < self.OldItems.Count; i++)
+ {
+ removeAt(self.OldItems[i], i + self.OldStartingIndex);
+ insert(self.OldItems[i], i + self.OldStartingIndex, true);
+ }
+ break;
+
+ case NotifyCollectionChangedAction.Reset:
+ reset();
+ return NotifyCollectionChangedAction.Reset;
+ }
+
+ return self.Action;
+ }
+
+ public static NotifyCollectionChangedEventArgsEx WithCount(this NotifyCollectionChangedEventArgs e, int count)
+ {
+ switch (e.Action)
+ {
+ case NotifyCollectionChangedAction.Add:
+ return new NotifyCollectionChangedEventArgsEx(count, NotifyCollectionChangedAction.Add, e.NewItems, e.NewStartingIndex);
+
+ case NotifyCollectionChangedAction.Remove:
+ return new NotifyCollectionChangedEventArgsEx(count, NotifyCollectionChangedAction.Remove, e.OldItems, e.OldStartingIndex);
+
+ case NotifyCollectionChangedAction.Move:
+ return new NotifyCollectionChangedEventArgsEx(count, NotifyCollectionChangedAction.Move, e.OldItems, e.NewStartingIndex, e.OldStartingIndex);
+
+ case NotifyCollectionChangedAction.Replace:
+ return new NotifyCollectionChangedEventArgsEx(count, NotifyCollectionChangedAction.Replace, e.NewItems, e.OldItems, e.OldStartingIndex);
+
+ default:
+ return new NotifyCollectionChangedEventArgsEx(count, NotifyCollectionChangedAction.Reset);
+ }
+ }
+ }
+} \ No newline at end of file