/// <summary> /// Sets the observable collection changes. /// </summary> /// <param name="propertyName">Name of the property.</param> /// <param name="changes">The changes.</param> /// <param name="sync">if set to <c>true</c> synchronize changes.</param> /// <exception cref="System.ArgumentNullException"> /// propertyName /// or /// changes /// </exception> /// <exception cref="PropertyNotFoundException"></exception> /// <exception cref="PropertyMismatchException"></exception> /// <exception cref="WriteOnlyPropertyException"></exception> internal void SetObservableCollectionChanges(string propertyName, ObservableCollectionChanges changes, bool sync) { if (string.IsNullOrWhiteSpace(propertyName)) { throw new ArgumentNullException("propertyName"); } if (changes == null) { throw new ArgumentNullException("changes"); } var property = FindProperty(propertyName); if (property == null) { throw new PropertyNotFoundException(propertyName, Name); } if (!property.IsCollection) { throw new PropertyMismatchException(Name, property.Name, string.Format("{0}/{1}", typeof(IList).Name, typeof(IList <>).Name), property.PropertyType.Name); } if (!property.Access.HasFlag(Access.Read)) { throw new WriteOnlyPropertyException(property.Name, Name); } var collection = property.GetDelegate.DynamicInvoke(this); if (collection != null) { if (property.IsArray) { SetArrayChanges((Array)collection, property, changes, sync); } else if (property.IsIList) { SetIListChanges((IList)collection, property, changes, sync); } else { SetGenericIListChanges(collection, property, changes, sync); } } }
/// <summary> /// Sets the Array changes. /// </summary> /// <param name="array">The array.</param> /// <param name="property">The property.</param> /// <param name="changes">The changes.</param> /// <param name="sync">if set to <c>true</c> synchronize changes.</param> private void SetArrayChanges(Array array, ControllerProperty property, ObservableCollectionChanges changes, bool sync) { // TODO; fix throw exceptions try { SyncChanges = sync; foreach (var change in changes.Actions) { if (change.Action == ObservableCollectionChangeAction.Add) { throw new PropertyMismatchException(Name, property.Name, string.Format("{0}/{1}", typeof(IList).Name, typeof(IList <>).Name), property.PropertyType.Name); } else if (change.Action == ObservableCollectionChangeAction.Remove) { throw new PropertyMismatchException(Name, property.Name, string.Format("{0}/{1}", typeof(IList).Name, typeof(IList <>).Name), property.PropertyType.Name); } else if (change.Action == ObservableCollectionChangeAction.Replace) { var startIndex = change.NewStartingIndex.Value; foreach (var item in change.NewItems) { if (startIndex >= array.Length) { throw new PropertyMismatchException(Name, property.Name, string.Format("{0}/{1}", typeof(IList).Name, typeof(IList <>).Name), property.PropertyType.Name); } array.SetValue(item.ToObject(property.ArrayType), startIndex); startIndex++; } } } } finally { SyncChanges = true; } }
private void CollectionChangedHandle(object sender, NotifyCollectionChangedEventArgs e, ControllerProperty property) { if (!SyncChanges) { return; } if (!ObservableCollectionChanges.ContainsKey(property.Name)) { ObservableCollectionChanges.Add(property.Name, new ObservableCollectionChanges { Name = property.Name }); } var changes = ObservableCollectionChanges[property.Name]; if (!changes.IsReset) { switch (e.Action) { case NotifyCollectionChangedAction.Add: changes.Actions.Add(new ObservableCollectionChange { NewItems = new JArray(e.NewItems), NewStartingIndex = e.NewStartingIndex, Action = ObservableCollectionChangeAction.Add }); break; case NotifyCollectionChangedAction.Move: changes.Actions.Add(new ObservableCollectionChange { OldStartingIndex = e.OldStartingIndex, NewStartingIndex = e.NewStartingIndex, Action = ObservableCollectionChangeAction.Move }); break; case NotifyCollectionChangedAction.Remove: changes.Actions.Add(new ObservableCollectionChange { OldStartingIndex = e.OldStartingIndex, Action = ObservableCollectionChangeAction.Remove }); break; case NotifyCollectionChangedAction.Replace: changes.Actions.Add(new ObservableCollectionChange { NewItems = new JArray(e.NewItems), NewStartingIndex = e.NewStartingIndex, Action = ObservableCollectionChangeAction.Replace }); break; case NotifyCollectionChangedAction.Reset: changes.Actions = new List <ObservableCollectionChange>(); changes.IsReset = true; break; } } }
/// <summary> /// Sets the generic IList changes. /// </summary> /// <param name="list">The list.</param> /// <param name="property">The property.</param> /// <param name="changes">The changes.</param> /// <param name="sync">if set to <c>true</c> synchronize changes.</param> private void SetGenericIListChanges(object list, ControllerProperty property, ObservableCollectionChanges changes, bool sync) { try { SyncChanges = sync; foreach (var change in changes.Actions) { if (change.Action == ObservableCollectionChangeAction.Add) { var startIndex = change.NewStartingIndex.Value; foreach (var item in change.NewItems) { PadGenericIList(list, property, startIndex); if (startIndex >= property.GenericIListCount(list)) { property.GenericIListAdd(list, item.ToObject(property.GenericIListType)); } else { property.GenericIListInsert(list, startIndex, item.ToObject(property.GenericIListType)); } startIndex++; } } else if (change.Action == ObservableCollectionChangeAction.Remove) { var removeIndex = change.OldStartingIndex.Value; if (property.GenericIListCount(list) > removeIndex) { property.GenericIListRemoveAt(list, removeIndex); } } else if (change.Action == ObservableCollectionChangeAction.Replace) { var startIndex = change.NewStartingIndex.Value; foreach (var item in change.NewItems) { PadGenericIList(list, property, startIndex); if (startIndex >= property.GenericIListCount(list)) { property.GenericIListAdd(list, item.ToObject(property.GenericIListType)); } else { property.GenericIListReplace(list, startIndex, item.ToObject(property.GenericIListType)); } startIndex++; } } } } finally { SyncChanges = true; } }
/// <summary> /// Sets the IList changes. /// </summary> /// <param name="list">The list.</param> /// <param name="property">The property.</param> /// <param name="changes">The changes.</param> /// <param name="sync">if set to <c>true</c> synchronize changes.</param> private void SetIListChanges(IList list, ControllerProperty property, ObservableCollectionChanges changes, bool sync) { try { SyncChanges = sync; var itemType = property.IsGenericIList ? property.GenericIListType : typeof(object); foreach (var change in changes.Actions) { if (change.Action == ObservableCollectionChangeAction.Add) { var startIndex = change.NewStartingIndex.Value; foreach (var item in change.NewItems) { PadIList(list, startIndex, itemType); if (startIndex >= list.Count) { list.Add(item.ToObject(itemType)); } else { list.Insert(startIndex, item.ToObject(itemType)); } startIndex++; } } else if (change.Action == ObservableCollectionChangeAction.Remove) { var removeIndex = change.OldStartingIndex.Value; if (list.Count > removeIndex) { list.RemoveAt(removeIndex); } } else if (change.Action == ObservableCollectionChangeAction.Replace) { var startIndex = change.NewStartingIndex.Value; foreach (var item in change.NewItems) { PadIList(list, startIndex, itemType); if (startIndex >= list.Count) { list.Add(item.ToObject(itemType)); } else { list[startIndex] = item.ToObject(itemType); } startIndex++; } } } } finally { SyncChanges = true; } }
/// <summary> /// Sets the observable collection changes. /// </summary> /// <param name="propertyName">Name of the property.</param> /// <param name="changes">The changes.</param> internal void SetObservableCollectionChanges(string propertyName, ObservableCollectionChanges changes) { SetObservableCollectionChanges(propertyName, changes, false); }
/// <summary> /// Clears the changes. /// </summary> internal void ClearChanges() { PropertyChanges.Clear(); ObservableCollectionChanges.Clear(); }