2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Collections.ObjectModel;
5 using System.Collections.Specialized;
8 namespace Tizen.NUI.XamlBinding
10 internal class ObservableWrapper<TTrack, TRestrict> : IList<TRestrict>, INotifyCollectionChanged where TTrack : Element where TRestrict : TTrack
12 readonly ObservableCollection<TTrack> _list;
14 public ObservableWrapper(ObservableCollection<TTrack> list)
17 throw new ArgumentNullException("list");
21 list.CollectionChanged += ListOnCollectionChanged;
24 public void Add(TRestrict item)
27 throw new ArgumentNullException("item");
29 throw new NotSupportedException("The collection is read-only.");
31 if (_list.Contains(item))
41 throw new NotSupportedException("The collection is read-only.");
43 foreach (TRestrict item in _list.OfType<TRestrict>().ToArray())
50 public bool Contains(TRestrict item)
52 return item.Owned && _list.Contains(item);
55 public void CopyTo(TRestrict[] array, int destIndex)
57 if (array.Length - destIndex < Count)
58 throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
59 foreach (TRestrict item in this)
61 array[destIndex] = item;
68 get { return _list.Where(i => i.Owned).OfType<TRestrict>().Count(); }
71 public bool IsReadOnly { get; internal set; }
73 public bool Remove(TRestrict item)
76 throw new ArgumentNullException("item");
78 throw new NotSupportedException("The collection is read-only.");
83 if (_list.Remove(item))
91 IEnumerator IEnumerable.GetEnumerator()
93 return GetEnumerator();
96 public IEnumerator<TRestrict> GetEnumerator()
98 return _list.Where(i => i.Owned).OfType<TRestrict>().GetEnumerator();
101 public int IndexOf(TRestrict value)
103 int innerIndex = _list.IndexOf(value);
104 if (innerIndex == -1)
106 return ToOuterIndex(innerIndex);
109 public void Insert(int index, TRestrict item)
112 throw new ArgumentNullException("item");
114 throw new NotSupportedException("The collection is read-only.");
117 _list.Insert(ToInnerIndex(index), item);
120 public TRestrict this[int index]
122 get { return (TRestrict)_list[ToInnerIndex(index)]; }
125 int innerIndex = ToInnerIndex(index);
128 TTrack old = _list[innerIndex];
129 _list[innerIndex] = value;
136 public void RemoveAt(int index)
139 throw new NotSupportedException("The collection is read-only");
140 int innerIndex = ToInnerIndex(index);
141 TTrack item = _list[innerIndex];
142 if (item != null && item.Owned)
144 _list.RemoveAt(innerIndex);
149 public event NotifyCollectionChangedEventHandler CollectionChanged;
151 void ListOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
153 NotifyCollectionChangedEventHandler handler = CollectionChanged;
159 case NotifyCollectionChangedAction.Add:
160 if (e.NewStartingIndex == -1 || e.NewItems?.Count > 1)
161 goto case NotifyCollectionChangedAction.Reset;
163 var newItem = e.NewItems[0] as TRestrict;
164 if (newItem == null || !newItem.Owned)
167 int outerIndex = ToOuterIndex(e.NewStartingIndex);
168 handler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, e.NewItems, outerIndex));
170 case NotifyCollectionChangedAction.Move:
171 if (e.NewStartingIndex == -1 || e.OldStartingIndex == -1 || e.NewItems?.Count > 1)
172 goto case NotifyCollectionChangedAction.Reset;
174 var movedItem = e.NewItems[0] as TRestrict;
175 if (movedItem == null || !movedItem.Owned)
178 int outerOldIndex = ToOuterIndex(e.OldStartingIndex);
179 int outerNewIndex = ToOuterIndex(e.NewStartingIndex);
180 handler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, e.NewItems, outerNewIndex, outerOldIndex));
182 case NotifyCollectionChangedAction.Remove:
183 if (e.OldStartingIndex == -1 || e.OldItems?.Count > 1)
184 goto case NotifyCollectionChangedAction.Reset;
186 var removedItem = e.OldItems[0] as TRestrict;
187 if (removedItem == null || !removedItem.Owned)
190 int outerRemovedIndex = ToOuterIndex(e.OldStartingIndex);
191 var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removedItem, outerRemovedIndex);
194 case NotifyCollectionChangedAction.Replace:
195 if (e.NewStartingIndex == -1 || e.OldStartingIndex == -1 || e.NewItems?.Count > 1)
196 goto case NotifyCollectionChangedAction.Reset;
198 var newReplaceItem = e.NewItems[0] as TRestrict;
199 var oldReplaceItem = e.OldItems?[0] as TRestrict;
201 if ((newReplaceItem == null || !newReplaceItem.Owned) && (oldReplaceItem == null || !oldReplaceItem.Owned))
205 if (newReplaceItem == null || !newReplaceItem.Owned || oldReplaceItem == null || !oldReplaceItem.Owned)
207 goto case NotifyCollectionChangedAction.Reset;
210 int index = ToOuterIndex(e.NewStartingIndex);
212 var replaceArgs = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newReplaceItem, oldReplaceItem, index);
213 handler(this, replaceArgs);
215 case NotifyCollectionChangedAction.Reset:
216 handler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
219 throw new ArgumentOutOfRangeException();
223 int ToInnerIndex(int outterIndex)
227 for (innerIndex = 0; innerIndex < _list.Count; innerIndex++)
229 TTrack item = _list[innerIndex];
230 if (item is TRestrict && item.Owned)
232 if (outerIndex == outterIndex)
241 int ToOuterIndex(int innerIndex)
244 for (var index = 0; index < innerIndex; index++)
246 TTrack item = _list[index];
247 if (item is TRestrict && item.Owned)