Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / CompMod / System / ComponentModel / BindingList.cs / 1 / BindingList.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Scope="type", Target="System.ComponentModel.BindingList`1")] namespace System.ComponentModel { using System; using System.Reflection; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Security.Permissions; using CodeAccessPermission = System.Security.CodeAccessPermission; ////// /// [HostProtection(SharedState = true)] [Serializable] public class BindingList: Collection , IBindingList, ICancelAddNew, IRaiseItemChangedEvents { private int addNewPos = -1; private bool raiseListChangedEvents = true; private bool raiseItemChangedEvents = false; [NonSerialized()] private PropertyDescriptorCollection itemTypeProperties = null; [NonSerialized()] private PropertyChangedEventHandler propertyChangedEventHandler = null; [NonSerialized()] private AddingNewEventHandler onAddingNew; [NonSerialized()] private ListChangedEventHandler onListChanged; [NonSerialized()] private int lastChangeIndex = -1; private bool allowNew = true; private bool allowEdit = true; private bool allowRemove = true; private bool userSetAllowNew = false; #region Constructors /// /// /// Default constructor. /// public BindingList() : base() { Initialize(); } ////// /// Constructor that allows substitution of the inner list with a custom list. /// public BindingList(IListlist) : base(list) { Initialize(); } private void Initialize() { // Set the default value of AllowNew based on whether type T has a default constructor this.allowNew = ItemTypeHasDefaultConstructor; // Check for INotifyPropertyChanged if (typeof(INotifyPropertyChanged).IsAssignableFrom(typeof(T))) { // Supports INotifyPropertyChanged this.raiseItemChangedEvents = true; // Loop thru the items already in the collection and hook their change notification. foreach (T item in this.Items) { HookPropertyChanged(item); } } } private bool ItemTypeHasDefaultConstructor { get { Type itemType = typeof(T); if (itemType.IsPrimitive) { return true; } if (itemType.GetConstructor(BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, null, new Type[0], null) != null) { return true; } return false; } } #endregion #region AddingNew event /// /// /// Event that allows a custom item to be provided as the new item added to the list by AddNew(). /// public event AddingNewEventHandler AddingNew { add { bool allowNewWasTrue = AllowNew; onAddingNew += value; if (allowNewWasTrue != AllowNew) { FireListChanged(ListChangedType.Reset, -1); } } remove { bool allowNewWasTrue = AllowNew; onAddingNew -= value; if (allowNewWasTrue != AllowNew) { FireListChanged(ListChangedType.Reset, -1); } } } ////// /// Raises the AddingNew event. /// protected virtual void OnAddingNew(AddingNewEventArgs e) { if (onAddingNew != null) { onAddingNew(this, e); } } // Private helper method private object FireAddingNew() { AddingNewEventArgs e = new AddingNewEventArgs(null); OnAddingNew(e); return e.NewObject; } #endregion #region ListChanged event ////// /// Event that reports changes to the list or to items in the list. /// public event ListChangedEventHandler ListChanged { add { onListChanged += value; } remove { onListChanged -= value; } } ////// /// Raises the ListChanged event. /// protected virtual void OnListChanged(ListChangedEventArgs e) { if (onListChanged != null) { onListChanged(this, e); } } ////// /// public void ResetBindings() { FireListChanged(ListChangedType.Reset, -1); } ////// /// public void ResetItem(int position) { FireListChanged(ListChangedType.ItemChanged, position); } // Private helper method private void FireListChanged(ListChangedType type, int index) { if (this.raiseListChangedEvents) { OnListChanged(new ListChangedEventArgs(type, index)); } } #endregion #region Collectionoverrides // Collection funnels all list changes through the four virtual methods below. // We override these so that we can commit any pending new item and fire the proper ListChanged events. protected override void ClearItems() { EndNew(addNewPos); if (this.raiseItemChangedEvents) { foreach (T item in this.Items) { UnhookPropertyChanged(item); } } base.ClearItems(); FireListChanged(ListChangedType.Reset, -1); } protected override void InsertItem(int index, T item) { EndNew(addNewPos); base.InsertItem(index, item); if (this.raiseItemChangedEvents) { HookPropertyChanged(item); } FireListChanged(ListChangedType.ItemAdded, index); } protected override void RemoveItem(int index) { // Need to all RemoveItem if this on the AddNew item if (!this.allowRemove && !(this.addNewPos >= 0 && this.addNewPos == index)) { throw new NotSupportedException(); } EndNew(addNewPos); if (this.raiseItemChangedEvents) { UnhookPropertyChanged(this[index]); } base.RemoveItem(index); FireListChanged(ListChangedType.ItemDeleted, index); } protected override void SetItem(int index, T item) { if (this.raiseItemChangedEvents) { UnhookPropertyChanged(this[index]); } base.SetItem(index, item); if (this.raiseItemChangedEvents) { HookPropertyChanged(item); } FireListChanged(ListChangedType.ItemChanged, index); } #endregion #region ICancelAddNew interface /// /// /// If item added using AddNew() is still cancellable, then remove that item from the list. /// public virtual void CancelNew(int itemIndex) { if (addNewPos >= 0 && addNewPos == itemIndex) { RemoveItem(addNewPos); addNewPos = -1; } } ////// /// If item added using AddNew() is still cancellable, then commit that item. /// public virtual void EndNew(int itemIndex) { if (addNewPos >= 0 && addNewPos == itemIndex) { addNewPos = -1; } } #endregion #region IBindingList interface ////// /// Adds a new item to the list. Calls public T AddNew() { return (T)((this as IBindingList).AddNew()); } object IBindingList.AddNew() { // Create new item and add it to list object newItem = AddNewCore(); // Record position of new item (to support cancellation later on) addNewPos = (newItem != null) ? IndexOf((T) newItem) : -1; // Return new item to caller return newItem; } private bool AddingNewHandled { get { return onAddingNew != null && onAddingNew.GetInvocationList().Length > 0; } } ///to create and add the item. /// /// Add operations are cancellable via the interface. The position of the /// new item is tracked until the add operation is either cancelled by a call to , /// explicitly commited by a call to , or implicitly commmited some other operation /// that changes the contents of the list (such as an Insert or Remove). When an add operation is /// cancelled, the new item is removed from the list. /// /// /// Creates a new item and adds it to the list. /// /// The base implementation raises the AddingNew event to allow an event handler to /// supply a custom item to add to the list. Otherwise an item of type T is created. /// The new item is then added to the end of the list. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2113:SecureLateBindingMethods")] protected virtual object AddNewCore() { // Allow event handler to supply the new item for us object newItem = FireAddingNew(); // If event hander did not supply new item, create one ourselves if (newItem == null) { Type type = typeof(T); newItem = SecurityUtils.SecureCreateInstance(type); } // Add item to end of list. Note: If event handler returned an item not of type T, // the cast below will trigger an InvalidCastException. This is by design. Add((T) newItem); // Return new item to caller return newItem; } ////// /// public bool AllowNew { get { //If the user set AllowNew, return what they set. If we have a default constructor, allowNew will be //true and we should just return true. if (userSetAllowNew || allowNew) { return this.allowNew; } //Even if the item doesn't have a default constructor, the user can hook AddingNew to provide an item. //If there's a handler for this, we should allow new. return AddingNewHandled; } set { bool oldAllowNewValue = AllowNew; userSetAllowNew = true; //Note that we don't want to set allowNew only if AllowNew didn't match value, //since AllowNew can depend on onAddingNew handler this.allowNew = value; if (oldAllowNewValue != value) { FireListChanged(ListChangedType.Reset, -1); } } } /* private */ bool IBindingList.AllowNew { get { return AllowNew; } } ////// /// public bool AllowEdit { get { return this.allowEdit; } set { if (this.allowEdit != value) { this.allowEdit = value; FireListChanged(ListChangedType.Reset, -1); } } } /* private */ bool IBindingList.AllowEdit { get { return AllowEdit; } } ////// /// public bool AllowRemove { get { return this.allowRemove; } set { if (this.allowRemove != value) { this.allowRemove = value; FireListChanged(ListChangedType.Reset, -1); } } } /* private */ bool IBindingList.AllowRemove { get { return AllowRemove; } } bool IBindingList.SupportsChangeNotification { get { return SupportsChangeNotificationCore; } } protected virtual bool SupportsChangeNotificationCore { get { return true; } } bool IBindingList.SupportsSearching { get { return SupportsSearchingCore; } } protected virtual bool SupportsSearchingCore { get { return false; } } bool IBindingList.SupportsSorting { get { return SupportsSortingCore; } } protected virtual bool SupportsSortingCore { get { return false; } } bool IBindingList.IsSorted { get { return IsSortedCore; } } protected virtual bool IsSortedCore { get { return false; } } PropertyDescriptor IBindingList.SortProperty { get { return SortPropertyCore; } } protected virtual PropertyDescriptor SortPropertyCore { get { return null; } } ListSortDirection IBindingList.SortDirection { get { return SortDirectionCore; } } protected virtual ListSortDirection SortDirectionCore { get { return ListSortDirection.Ascending; } } void IBindingList.ApplySort(PropertyDescriptor prop, ListSortDirection direction) { ApplySortCore(prop, direction); } protected virtual void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) { throw new NotSupportedException(); } void IBindingList.RemoveSort() { RemoveSortCore(); } protected virtual void RemoveSortCore() { throw new NotSupportedException(); } int IBindingList.Find(PropertyDescriptor prop, object key) { return FindCore(prop, key); } protected virtual int FindCore(PropertyDescriptor prop, object key) { throw new NotSupportedException(); } void IBindingList.AddIndex(PropertyDescriptor prop) { // Not supported } void IBindingList.RemoveIndex(PropertyDescriptor prop) { // Not supported } #endregion #region Property Change Support private void HookPropertyChanged(T item) { INotifyPropertyChanged inpc = (item as INotifyPropertyChanged); // Note: inpc may be null if item is null, so always check. if (null != inpc) { if (propertyChangedEventHandler == null) { propertyChangedEventHandler = new PropertyChangedEventHandler(Child_PropertyChanged); } inpc.PropertyChanged += propertyChangedEventHandler; } } private void UnhookPropertyChanged(T item) { INotifyPropertyChanged inpc = (item as INotifyPropertyChanged); // Note: inpc may be null if item is null, so always check. if (null != inpc && null != propertyChangedEventHandler) { inpc.PropertyChanged -= propertyChangedEventHandler; } } void Child_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (this.RaiseListChangedEvents) { if (sender == null || e == null || string.IsNullOrEmpty(e.PropertyName)) { // Fire reset event (per INotifyPropertyChanged spec) ResetBindings(); } else { // The change event is broken should someone pass an item to us that is not // of type T. Still, if they do so, detect it and ----. It is an incorrect // and rare enough occurrence that we do not want to slow the mainline path // with "is" checks. T item; try { item = (T)sender; } catch(InvalidCastException) { ResetBindings(); return; } // Find the position of the item. This should never be -1. If it is, // somehow the item has been removed from our list without our knowledge. int pos = lastChangeIndex; if (pos < 0 || pos >= Count || !this[pos].Equals(item)) { pos = this.IndexOf(item); lastChangeIndex = pos; } if (pos == -1) { Debug.Fail("Item is no longer in our list but we are still getting change notifications."); UnhookPropertyChanged(item); ResetBindings(); } else { // Get the property descriptor if (null == this.itemTypeProperties) { // Get Shape itemTypeProperties = TypeDescriptor.GetProperties(typeof(T)); Debug.Assert(itemTypeProperties != null); } PropertyDescriptor pd = itemTypeProperties.Find(e.PropertyName, true); // Create event args. If there was no matching property descriptor, // we raise the list changed anyway. ListChangedEventArgs args = new ListChangedEventArgs(ListChangedType.ItemChanged, pos, pd); // Fire the ItemChanged event OnListChanged(args); } } } } #endregion #region IRaiseItemChangedEvents interface ////// /// Returns false to indicate that BindingList bool IRaiseItemChangedEvents.RaisesItemChangedEvents { get { return this.raiseItemChangedEvents; } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //does NOT raise ListChanged events /// of type ItemChanged as a result of property changes on individual list items /// unless those items support INotifyPropertyChanged /// // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Scope="type", Target="System.ComponentModel.BindingList`1")] namespace System.ComponentModel { using System; using System.Reflection; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Security.Permissions; using CodeAccessPermission = System.Security.CodeAccessPermission; ////// /// [HostProtection(SharedState = true)] [Serializable] public class BindingList: Collection , IBindingList, ICancelAddNew, IRaiseItemChangedEvents { private int addNewPos = -1; private bool raiseListChangedEvents = true; private bool raiseItemChangedEvents = false; [NonSerialized()] private PropertyDescriptorCollection itemTypeProperties = null; [NonSerialized()] private PropertyChangedEventHandler propertyChangedEventHandler = null; [NonSerialized()] private AddingNewEventHandler onAddingNew; [NonSerialized()] private ListChangedEventHandler onListChanged; [NonSerialized()] private int lastChangeIndex = -1; private bool allowNew = true; private bool allowEdit = true; private bool allowRemove = true; private bool userSetAllowNew = false; #region Constructors /// /// /// Default constructor. /// public BindingList() : base() { Initialize(); } ////// /// Constructor that allows substitution of the inner list with a custom list. /// public BindingList(IListlist) : base(list) { Initialize(); } private void Initialize() { // Set the default value of AllowNew based on whether type T has a default constructor this.allowNew = ItemTypeHasDefaultConstructor; // Check for INotifyPropertyChanged if (typeof(INotifyPropertyChanged).IsAssignableFrom(typeof(T))) { // Supports INotifyPropertyChanged this.raiseItemChangedEvents = true; // Loop thru the items already in the collection and hook their change notification. foreach (T item in this.Items) { HookPropertyChanged(item); } } } private bool ItemTypeHasDefaultConstructor { get { Type itemType = typeof(T); if (itemType.IsPrimitive) { return true; } if (itemType.GetConstructor(BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, null, new Type[0], null) != null) { return true; } return false; } } #endregion #region AddingNew event /// /// /// Event that allows a custom item to be provided as the new item added to the list by AddNew(). /// public event AddingNewEventHandler AddingNew { add { bool allowNewWasTrue = AllowNew; onAddingNew += value; if (allowNewWasTrue != AllowNew) { FireListChanged(ListChangedType.Reset, -1); } } remove { bool allowNewWasTrue = AllowNew; onAddingNew -= value; if (allowNewWasTrue != AllowNew) { FireListChanged(ListChangedType.Reset, -1); } } } ////// /// Raises the AddingNew event. /// protected virtual void OnAddingNew(AddingNewEventArgs e) { if (onAddingNew != null) { onAddingNew(this, e); } } // Private helper method private object FireAddingNew() { AddingNewEventArgs e = new AddingNewEventArgs(null); OnAddingNew(e); return e.NewObject; } #endregion #region ListChanged event ////// /// Event that reports changes to the list or to items in the list. /// public event ListChangedEventHandler ListChanged { add { onListChanged += value; } remove { onListChanged -= value; } } ////// /// Raises the ListChanged event. /// protected virtual void OnListChanged(ListChangedEventArgs e) { if (onListChanged != null) { onListChanged(this, e); } } ////// /// public void ResetBindings() { FireListChanged(ListChangedType.Reset, -1); } ////// /// public void ResetItem(int position) { FireListChanged(ListChangedType.ItemChanged, position); } // Private helper method private void FireListChanged(ListChangedType type, int index) { if (this.raiseListChangedEvents) { OnListChanged(new ListChangedEventArgs(type, index)); } } #endregion #region Collectionoverrides // Collection funnels all list changes through the four virtual methods below. // We override these so that we can commit any pending new item and fire the proper ListChanged events. protected override void ClearItems() { EndNew(addNewPos); if (this.raiseItemChangedEvents) { foreach (T item in this.Items) { UnhookPropertyChanged(item); } } base.ClearItems(); FireListChanged(ListChangedType.Reset, -1); } protected override void InsertItem(int index, T item) { EndNew(addNewPos); base.InsertItem(index, item); if (this.raiseItemChangedEvents) { HookPropertyChanged(item); } FireListChanged(ListChangedType.ItemAdded, index); } protected override void RemoveItem(int index) { // Need to all RemoveItem if this on the AddNew item if (!this.allowRemove && !(this.addNewPos >= 0 && this.addNewPos == index)) { throw new NotSupportedException(); } EndNew(addNewPos); if (this.raiseItemChangedEvents) { UnhookPropertyChanged(this[index]); } base.RemoveItem(index); FireListChanged(ListChangedType.ItemDeleted, index); } protected override void SetItem(int index, T item) { if (this.raiseItemChangedEvents) { UnhookPropertyChanged(this[index]); } base.SetItem(index, item); if (this.raiseItemChangedEvents) { HookPropertyChanged(item); } FireListChanged(ListChangedType.ItemChanged, index); } #endregion #region ICancelAddNew interface /// /// /// If item added using AddNew() is still cancellable, then remove that item from the list. /// public virtual void CancelNew(int itemIndex) { if (addNewPos >= 0 && addNewPos == itemIndex) { RemoveItem(addNewPos); addNewPos = -1; } } ////// /// If item added using AddNew() is still cancellable, then commit that item. /// public virtual void EndNew(int itemIndex) { if (addNewPos >= 0 && addNewPos == itemIndex) { addNewPos = -1; } } #endregion #region IBindingList interface ////// /// Adds a new item to the list. Calls public T AddNew() { return (T)((this as IBindingList).AddNew()); } object IBindingList.AddNew() { // Create new item and add it to list object newItem = AddNewCore(); // Record position of new item (to support cancellation later on) addNewPos = (newItem != null) ? IndexOf((T) newItem) : -1; // Return new item to caller return newItem; } private bool AddingNewHandled { get { return onAddingNew != null && onAddingNew.GetInvocationList().Length > 0; } } ///to create and add the item. /// /// Add operations are cancellable via the interface. The position of the /// new item is tracked until the add operation is either cancelled by a call to , /// explicitly commited by a call to , or implicitly commmited some other operation /// that changes the contents of the list (such as an Insert or Remove). When an add operation is /// cancelled, the new item is removed from the list. /// /// /// Creates a new item and adds it to the list. /// /// The base implementation raises the AddingNew event to allow an event handler to /// supply a custom item to add to the list. Otherwise an item of type T is created. /// The new item is then added to the end of the list. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2113:SecureLateBindingMethods")] protected virtual object AddNewCore() { // Allow event handler to supply the new item for us object newItem = FireAddingNew(); // If event hander did not supply new item, create one ourselves if (newItem == null) { Type type = typeof(T); newItem = SecurityUtils.SecureCreateInstance(type); } // Add item to end of list. Note: If event handler returned an item not of type T, // the cast below will trigger an InvalidCastException. This is by design. Add((T) newItem); // Return new item to caller return newItem; } ////// /// public bool AllowNew { get { //If the user set AllowNew, return what they set. If we have a default constructor, allowNew will be //true and we should just return true. if (userSetAllowNew || allowNew) { return this.allowNew; } //Even if the item doesn't have a default constructor, the user can hook AddingNew to provide an item. //If there's a handler for this, we should allow new. return AddingNewHandled; } set { bool oldAllowNewValue = AllowNew; userSetAllowNew = true; //Note that we don't want to set allowNew only if AllowNew didn't match value, //since AllowNew can depend on onAddingNew handler this.allowNew = value; if (oldAllowNewValue != value) { FireListChanged(ListChangedType.Reset, -1); } } } /* private */ bool IBindingList.AllowNew { get { return AllowNew; } } ////// /// public bool AllowEdit { get { return this.allowEdit; } set { if (this.allowEdit != value) { this.allowEdit = value; FireListChanged(ListChangedType.Reset, -1); } } } /* private */ bool IBindingList.AllowEdit { get { return AllowEdit; } } ////// /// public bool AllowRemove { get { return this.allowRemove; } set { if (this.allowRemove != value) { this.allowRemove = value; FireListChanged(ListChangedType.Reset, -1); } } } /* private */ bool IBindingList.AllowRemove { get { return AllowRemove; } } bool IBindingList.SupportsChangeNotification { get { return SupportsChangeNotificationCore; } } protected virtual bool SupportsChangeNotificationCore { get { return true; } } bool IBindingList.SupportsSearching { get { return SupportsSearchingCore; } } protected virtual bool SupportsSearchingCore { get { return false; } } bool IBindingList.SupportsSorting { get { return SupportsSortingCore; } } protected virtual bool SupportsSortingCore { get { return false; } } bool IBindingList.IsSorted { get { return IsSortedCore; } } protected virtual bool IsSortedCore { get { return false; } } PropertyDescriptor IBindingList.SortProperty { get { return SortPropertyCore; } } protected virtual PropertyDescriptor SortPropertyCore { get { return null; } } ListSortDirection IBindingList.SortDirection { get { return SortDirectionCore; } } protected virtual ListSortDirection SortDirectionCore { get { return ListSortDirection.Ascending; } } void IBindingList.ApplySort(PropertyDescriptor prop, ListSortDirection direction) { ApplySortCore(prop, direction); } protected virtual void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) { throw new NotSupportedException(); } void IBindingList.RemoveSort() { RemoveSortCore(); } protected virtual void RemoveSortCore() { throw new NotSupportedException(); } int IBindingList.Find(PropertyDescriptor prop, object key) { return FindCore(prop, key); } protected virtual int FindCore(PropertyDescriptor prop, object key) { throw new NotSupportedException(); } void IBindingList.AddIndex(PropertyDescriptor prop) { // Not supported } void IBindingList.RemoveIndex(PropertyDescriptor prop) { // Not supported } #endregion #region Property Change Support private void HookPropertyChanged(T item) { INotifyPropertyChanged inpc = (item as INotifyPropertyChanged); // Note: inpc may be null if item is null, so always check. if (null != inpc) { if (propertyChangedEventHandler == null) { propertyChangedEventHandler = new PropertyChangedEventHandler(Child_PropertyChanged); } inpc.PropertyChanged += propertyChangedEventHandler; } } private void UnhookPropertyChanged(T item) { INotifyPropertyChanged inpc = (item as INotifyPropertyChanged); // Note: inpc may be null if item is null, so always check. if (null != inpc && null != propertyChangedEventHandler) { inpc.PropertyChanged -= propertyChangedEventHandler; } } void Child_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (this.RaiseListChangedEvents) { if (sender == null || e == null || string.IsNullOrEmpty(e.PropertyName)) { // Fire reset event (per INotifyPropertyChanged spec) ResetBindings(); } else { // The change event is broken should someone pass an item to us that is not // of type T. Still, if they do so, detect it and ----. It is an incorrect // and rare enough occurrence that we do not want to slow the mainline path // with "is" checks. T item; try { item = (T)sender; } catch(InvalidCastException) { ResetBindings(); return; } // Find the position of the item. This should never be -1. If it is, // somehow the item has been removed from our list without our knowledge. int pos = lastChangeIndex; if (pos < 0 || pos >= Count || !this[pos].Equals(item)) { pos = this.IndexOf(item); lastChangeIndex = pos; } if (pos == -1) { Debug.Fail("Item is no longer in our list but we are still getting change notifications."); UnhookPropertyChanged(item); ResetBindings(); } else { // Get the property descriptor if (null == this.itemTypeProperties) { // Get Shape itemTypeProperties = TypeDescriptor.GetProperties(typeof(T)); Debug.Assert(itemTypeProperties != null); } PropertyDescriptor pd = itemTypeProperties.Find(e.PropertyName, true); // Create event args. If there was no matching property descriptor, // we raise the list changed anyway. ListChangedEventArgs args = new ListChangedEventArgs(ListChangedType.ItemChanged, pos, pd); // Fire the ItemChanged event OnListChanged(args); } } } } #endregion #region IRaiseItemChangedEvents interface ////// /// Returns false to indicate that BindingList bool IRaiseItemChangedEvents.RaisesItemChangedEvents { get { return this.raiseItemChangedEvents; } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.does NOT raise ListChanged events /// of type ItemChanged as a result of property changes on individual list items /// unless those items support INotifyPropertyChanged ///
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- QueryCacheKey.cs
- FilterException.cs
- CatalogZoneBase.cs
- SystemIcmpV6Statistics.cs
- StrokeSerializer.cs
- Stackframe.cs
- ByteStorage.cs
- Track.cs
- DataGridViewControlCollection.cs
- XmlNodeReader.cs
- PopupRootAutomationPeer.cs
- ThemeDictionaryExtension.cs
- designeractionbehavior.cs
- AutoResizedEvent.cs
- MemberHolder.cs
- DataControlExtensions.cs
- dsa.cs
- UserControl.cs
- Parsers.cs
- TypefaceMetricsCache.cs
- TrackingStringDictionary.cs
- IsolatedStorageFilePermission.cs
- StyleSelector.cs
- ProcessModule.cs
- ValueTypeFixupInfo.cs
- XmlQueryCardinality.cs
- NetCodeGroup.cs
- ResourceContainer.cs
- SystemIPAddressInformation.cs
- XmlChildNodes.cs
- CodePageEncoding.cs
- WbmpConverter.cs
- HttpUnhandledOperationInvoker.cs
- ListViewInsertedEventArgs.cs
- SafeRightsManagementEnvironmentHandle.cs
- SimpleRecyclingCache.cs
- XmlSchemaInclude.cs
- DataColumnMapping.cs
- HttpPostedFile.cs
- UTF32Encoding.cs
- DatagridviewDisplayedBandsData.cs
- MouseEventArgs.cs
- Message.cs
- XPathNodeIterator.cs
- LocalizedNameDescriptionPair.cs
- FullTextBreakpoint.cs
- ListViewItem.cs
- GeometryGroup.cs
- ProcessModule.cs
- OptimisticConcurrencyException.cs
- IChannel.cs
- WebEventCodes.cs
- BaseHashHelper.cs
- LogRestartAreaEnumerator.cs
- OperationCanceledException.cs
- CustomErrorCollection.cs
- ObjectDataSourceFilteringEventArgs.cs
- SendSecurityHeaderElement.cs
- AlgoModule.cs
- VersionValidator.cs
- StylusPlugin.cs
- MouseWheelEventArgs.cs
- OleDbException.cs
- BezierSegment.cs
- DataSourceControlBuilder.cs
- PinnedBufferMemoryStream.cs
- NavigatingCancelEventArgs.cs
- CodeExpressionCollection.cs
- EntityDataSourceView.cs
- figurelength.cs
- SqlGenericUtil.cs
- ConfigXmlComment.cs
- Scheduler.cs
- AccessViolationException.cs
- SqlRecordBuffer.cs
- Int32.cs
- TextCompositionManager.cs
- Delegate.cs
- DashStyle.cs
- _emptywebproxy.cs
- UpdatableGenericsFeature.cs
- CompensatableTransactionScopeActivityDesigner.cs
- BindingList.cs
- Image.cs
- TrackingStringDictionary.cs
- srgsitem.cs
- DependencyObject.cs
- TdsParserHelperClasses.cs
- Signature.cs
- NodeFunctions.cs
- shaperfactoryquerycachekey.cs
- InitializationEventAttribute.cs
- KeyToListMap.cs
- ItemAutomationPeer.cs
- Trace.cs
- IdentityValidationException.cs
- TaskSchedulerException.cs
- CriticalFinalizerObject.cs
- SystemEvents.cs
- RegionIterator.cs