// When an item is removed, there could be any number of items to remove from the index, // so enqueue a new indexing operation that will be processed asynchronously private void OnItemRemoved(ModelObject parentObject, INotifyingCollection sender, IItemAddedRemovedEventArgs e) { if (e.Item is ModelObject) { this.EnqueueIndexingOperation((ModelObject)e.Item, IndexingOperation.Unregister); } }
private void RaiseItemReplacedEvent(INotifyingCollection sender, IItemReplacedEventArgs eventArgs) { if (this.ItemReplaced != null) { this.ItemReplaced(this.collectionOwners[sender], sender, eventArgs); } }
private void RecordObjectRemoved(INotifyingCollection parent, object modelObject, int index) { if (modelObject != null) { this.Add(new UndoableItemRemovedChange(parent, modelObject, index)); } }
/// <summary> /// Registers a ModelObject with this ModelWatcher. Property changed events /// and collection add/remove/replace events will be watched. /// </summary> /// <param name="modelObject">The ModelObject to watch.</param> private void RegisterModelObject(ModelObject modelObject) { // Make sure the ModelObject hasn't already been registered and isn't a blacklisted type if (modelObject != null) { if (this.registeredObjects.ContainsKey(modelObject)) { // This assert fails when processing properties that raise PropertyChanged events // when a value is first fetched. The property changed event gets hooked and // the read causes the model watcher to try to register the model object again. // Debug.Fail ("Model contains a cycle."); } else { // Add the type and register for property changed events this.registeredObjects.Add(modelObject, true); this.AddInstance(modelObject); modelObject.PropertyChanged += this.OnPropertyChanged; // Examine the properties of the ModelObject to look for more ModelObjects to monitor foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(modelObject)) { // Check if the property is owned by the current ModelObject if (propertyDescriptor.Attributes.Contains(RelationAttribute.Owner)) { // Check if the property itself is a ModelObject if (propertyDescriptor.PropertyType.IsSubclassOf(typeof(ModelObject))) { // Recurse on the ModelObject property this.RegisterModelObject((ModelObject)propertyDescriptor.GetValue(modelObject)); } // Check if the property is a collection of child ModelObjects else if (typeof(IEnumerable).IsAssignableFrom(propertyDescriptor.PropertyType)) { // Register for collection item add/remove/replace events INotifyingCollection notifyingCollection = propertyDescriptor.GetValue(modelObject) as INotifyingCollection; if (notifyingCollection != null && !this.collectionOwners.ContainsKey(notifyingCollection)) { notifyingCollection.ItemAdded += this.OnItemAdded; notifyingCollection.ItemRemoved += this.OnItemRemoved; notifyingCollection.ItemReplaced += this.OnItemReplaced; // Add a mapping between the collection and the object that owns it this.collectionOwners.Add(notifyingCollection, modelObject); // Recurse on ModelObject children foreach (object obj in notifyingCollection) { ModelObject childObject = obj as ModelObject; this.RegisterModelObject(childObject); } } } } } } } }
// When an item is added, there could be any number of new items to index // and old items to remove from the index, // so enqueue a new indexing operation that will be processed asynchronously private void OnItemReplaced(ModelObject parentObject, INotifyingCollection sender, IItemReplacedEventArgs e) { if (e.OldItem is ModelObject) { this.EnqueueIndexingOperation((ModelObject)e.OldItem, IndexingOperation.Unregister); } if (e.NewItem is ModelObject) { this.EnqueueIndexingOperation((ModelObject)e.NewItem, IndexingOperation.Register); } }
private void OnItemReplaced(ModelObject parentObject, INotifyingCollection sender, IItemReplacedEventArgs e) { if (e.OldItem != null) { this.RecordObjectRemoved(sender, e.OldItem, e.Index); } if (e.NewItem != null) { this.RecordObjectAdded(sender, e.NewItem, e.Index); } }
private void OnItemReplaced(INotifyingCollection sender, IItemReplacedEventArgs eventArgs) { if (eventArgs.OldItem != null) { this.UnregisterModelObject(eventArgs.OldItem as ModelObject); } if (eventArgs.NewItem != null) { this.RegisterModelObject(eventArgs.NewItem as ModelObject); } this.RaiseItemReplacedEvent(sender, eventArgs); }
/// <summary> /// Unregisters a ModelObject with this ModelWatcher. Events from the ModelObject /// will no longer be monitored. /// </summary> /// <param name="modelObject">The ModelObject to unregister.</param> private void UnregisterModelObject(ModelObject modelObject) { // Make sure the ModelObject is currently registered if (modelObject != null && this.registeredObjects.ContainsKey(modelObject)) { // Remove the type and unregister for property changed events this.registeredObjects.Remove(modelObject); this.RemoveInstance(modelObject); modelObject.PropertyChanged -= this.OnPropertyChanged; // Examine the properties of the ModelObject to look for more ModelObjects that are being monitored foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(modelObject)) { // Check if the property is owned by the current ModelObject if (propertyDescriptor.Attributes.Contains(RelationAttribute.Owner)) { // Check if the property itself is a ModelObject if (propertyDescriptor.PropertyType.IsSubclassOf(typeof(ModelObject))) { // Recurse on the ModelObject property this.UnregisterModelObject((ModelObject)propertyDescriptor.GetValue(modelObject)); } // Check if the property is a collection of child ModelObjects else if (typeof(IEnumerable).IsAssignableFrom(propertyDescriptor.PropertyType)) { // Unregister for collection item add/remove/replace events INotifyingCollection notifyingCollection = propertyDescriptor.GetValue(modelObject) as INotifyingCollection; if (notifyingCollection != null && this.collectionOwners.ContainsKey(notifyingCollection)) { notifyingCollection.ItemAdded -= this.OnItemAdded; notifyingCollection.ItemRemoved -= this.OnItemRemoved; notifyingCollection.ItemReplaced -= this.OnItemReplaced; // Remove the mapping between the collection and the object that owns it this.collectionOwners.Remove(notifyingCollection); // Recurse on ModelObject children foreach (object obj in notifyingCollection) { ModelObject childObject = obj as ModelObject; this.UnregisterModelObject(childObject); } } } } } } }
private void RegisterModelObject(ModelObject modelObject) { lock (this.registeredObjects) { // Make sure the ModelObject hasn't already been processed if (modelObject != null && !this.registeredObjects.Contains(modelObject)) { // Add the object to the list of already processed objects this.registeredObjects.Add(modelObject); // Add the object to the validation manager ISupportValidation obj = modelObject as ISupportValidation; if (obj != null) { this.AddObject(obj); this.BeginValidation(obj); } // Examine the properties of the ModelObject to look for more ModelObjects to process foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(modelObject)) { // Check if the property itself is a ModelObject if (propertyDescriptor.PropertyType.IsSubclassOf(typeof(ModelObject))) { // Recurse on the ModelObject property this.RegisterModelObject((ModelObject)propertyDescriptor.GetValue(modelObject)); } // Check if the property is a collection of child ModelObjects else if (typeof(IEnumerable).IsAssignableFrom(propertyDescriptor.PropertyType)) { INotifyingCollection notifyingCollection = propertyDescriptor.GetValue(modelObject) as INotifyingCollection; if (notifyingCollection != null) { // Recurse on ModelObject children foreach (object childObject in notifyingCollection) { this.RegisterModelObject(childObject as ModelObject); } } } } } } }
private void RegisterModelObject(ModelObject modelObject) { // Make sure the ModelObject hasn't already been processed if (modelObject != null && !this.registeredObjects.ContainsKey(modelObject)) { // Make sure the ModelObject is searchable if (this.GetSearchableAttribute(modelObject.GetType()).KeywordProvider != null) { // Add the object to the list of already processed objects this.registeredObjects.Add(modelObject, true); // Examine the properties of the ModelObject to look for more ModelObjects to process foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(modelObject)) { // Process the property if (this.RegisterProperty(modelObject, propertyDescriptor)) { // Check if the property itself is a ModelObject if (propertyDescriptor.PropertyType.IsSubclassOf(typeof(ModelObject))) { // Recurse on the ModelObject property this.RegisterModelObject((ModelObject)propertyDescriptor.GetValue(modelObject)); } // Check if the property is a collection of child ModelObjects else if (typeof(IEnumerable).IsAssignableFrom(propertyDescriptor.PropertyType)) { INotifyingCollection notifyingCollection = propertyDescriptor.GetValue(modelObject) as INotifyingCollection; if (notifyingCollection != null && !this.collectionOwners.ContainsKey(notifyingCollection)) { this.collectionOwners.Add(notifyingCollection, modelObject); // Recurse on ModelObject children foreach (object childObject in notifyingCollection) { this.RegisterModelObject(childObject as ModelObject); } } } } } } } }
private void UnregisterModelObject(ModelObject modelObject) { // Make sure the object was previously processed if (modelObject != null && this.registeredObjects.ContainsKey(modelObject)) { // Remove the object from the list of already processed objects this.registeredObjects.Remove(modelObject); // Examine the properties of the ModelObject to look for more ModelObjects to monitor foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(modelObject)) { // Remove the property if (this.UnregisterProperty(modelObject, propertyDescriptor)) { // Check if the property itself is a ModelObject if (propertyDescriptor.PropertyType.IsSubclassOf(typeof(ModelObject))) { // Recurse on the ModelObject property this.UnregisterModelObject((ModelObject)propertyDescriptor.GetValue(modelObject)); } // Check if the property is a collection of child ModelObjects else if (typeof(IEnumerable).IsAssignableFrom(propertyDescriptor.PropertyType)) { INotifyingCollection notifyingCollection = propertyDescriptor.GetValue(modelObject) as INotifyingCollection; if (notifyingCollection != null && this.collectionOwners.ContainsKey(notifyingCollection)) { this.collectionOwners.Remove(notifyingCollection); // Recurse on ModelObject children foreach (object childObject in notifyingCollection) { this.UnregisterModelObject(childObject as ModelObject); } } } } } } }
private void OnDataModelItemReplaced(ModelObject parentObject, INotifyingCollection sender, IItemReplacedEventArgs eventArgs) { this.OnDataModelInternalsChanged(); }
private void OnItemRemoved(INotifyingCollection sender, IItemAddedRemovedEventArgs eventArgs) { this.UnregisterModelObject(eventArgs.Item as ModelObject); this.RaiseItemRemovedEvent(sender, eventArgs); }
private void OnItemRemoved(ModelObject parentObject, INotifyingCollection sender, IItemAddedRemovedEventArgs e) { this.RecordObjectRemoved(sender, e.Item, e.Index); }
/// <summary> /// Initializes a new instance of the <see cref="UndoableCollectionChange"/> class. /// </summary> /// <param name="collection">The collection being changed.</param> /// <param name="value">The value of the changed item.</param> /// <param name="index">The index of the changed item.</param> public UndoableCollectionChange(INotifyingCollection collection, object value, int index) { this.collection = collection; this.value = value; this.index = index; }
/// <summary> /// Initializes a new instance of the <see cref="UndoableItemAddedChange"/> class. /// </summary> /// <param name="collection">The collection being changed.</param> /// <param name="value">The value of the changed item.</param> /// <param name="index">The index of the changed item.</param> public UndoableItemAddedChange(INotifyingCollection collection, object value, int index) : base(collection, value, index) { }
private void OnItemReplaced(ModelObject parentObject, INotifyingCollection sender, IItemReplacedEventArgs e) { this.UnregisterModelObject(e.OldItem as ModelObject); this.RegisterModelObject(e.NewItem as ModelObject); }
private void OnItemRemoved(ModelObject parentObject, INotifyingCollection sender, IItemAddedRemovedEventArgs e) { this.UnregisterModelObject(e.Item as ModelObject); }