Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Objects / ObjectView.cs / 1305376 / ObjectView.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data.Common; using System.Data.Metadata; using System.Data.Metadata.Edm; using System.Data.Objects.DataClasses; using System.Diagnostics; using System.Reflection; namespace System.Data.Objects { ////// Manages a list suitable for data binding. /// ////// The type of elements in the binding list. /// ////// internal class ObjectView/// This class provides an implementation of IBindingList that exposes a list of elements to be bound, /// provides a mechanism to change the membership of the list, /// and events to notify interested objects when the membership of the list is modified /// or an element in the list is modified. /// ////// ObjectView relies on an object that implements IObjectViewData to manage the binding list. /// See the documentation for IObjectViewData for details. /// ///: IBindingList, ICancelAddNew, IObjectView { /// /// Specifies whether events handled from an underlying collection or individual bound item /// should result in list change events being fired from this IBindingList. /// True to prevent events from being fired from this IBindingList; /// otherwise false to allow events to propogate. /// private bool _suspendEvent; // Delegate for IBindingList.ListChanged event. private ListChangedEventHandler onListChanged; ////// Object that listens for underlying collection or individual bound item changes, /// and notifies this object when they occur. /// private ObjectViewListener _listener; ////// Index of last item added via a call to IBindingList.AddNew. /// private int _addNewIndex = -1; ////// Object that maintains the underlying bound list, /// and specifies the operations allowed on that list. /// private IObjectViewData_viewData; /// /// Construct a new instance of ObjectView using the supplied IObjectViewData and event data source. /// /// /// Object that maintains the underlying bound list, /// and specifies the operations allowed on that list. /// /// /// Event source to "attach" to in order to listen to collection and item changes. /// internal ObjectView(IObjectViewDataviewData, object eventDataSource) { _viewData = viewData; _listener = new ObjectViewListener(this, (IList)_viewData.List, eventDataSource); } private void EnsureWritableList() { if (((IList)this).IsReadOnly) { throw EntityUtil.WriteOperationNotAllowedOnReadOnlyBindingList(); } } private bool IsElementTypeAbstract { get { return typeof(TElement).IsAbstract; } } #region ICancelAddNew implementation /// /// If a new item has been added to the list, and /// Index of item to be removed as a result of the cancellation of a previous addition. void ICancelAddNew.CancelNew(int itemIndex) { if (_addNewIndex >= 0 && itemIndex == _addNewIndex) { TElement item = _viewData.List[_addNewIndex]; _listener.UnregisterEntityEvents(item); int oldIndex = _addNewIndex; // Reset the addNewIndex here so that the IObjectView.CollectionChanged method // will not attempt to examine the item being removed. // See IObjectView.CollectionChanged method for details. _addNewIndex = -1; try { _suspendEvent = true; _viewData.Remove(item, true); } finally { _suspendEvent = false; } OnListChanged(ListChangedType.ItemDeleted, oldIndex, -1); } } ///is the position of that item, /// remove it from the list and cancel the add operation. /// /// Commit a new item to the binding list. /// /// /// Index of item to be committed. /// This index must match the index of the item created by the last call to IBindindList.AddNew; /// otherwise this method is a nop. /// void ICancelAddNew.EndNew(int itemIndex) { if (_addNewIndex >= 0 && itemIndex == _addNewIndex) { _viewData.CommitItemAt(_addNewIndex); _addNewIndex = -1; } } #endregion #region IBindingList implementation bool IBindingList.AllowNew { get { return _viewData.AllowNew && !IsElementTypeAbstract; } } bool IBindingList.AllowEdit { get { return _viewData.AllowEdit; } } object IBindingList.AddNew() { EnsureWritableList(); if (IsElementTypeAbstract) { throw EntityUtil.AddNewOperationNotAllowedOnAbstractBindingList(); } _viewData.EnsureCanAddNew(); ((ICancelAddNew)this).EndNew(_addNewIndex); TElement newItem = (TElement)Activator.CreateInstance(typeof(TElement)); _addNewIndex = _viewData.Add(newItem, true); _listener.RegisterEntityEvents(newItem); OnListChanged(ListChangedType.ItemAdded, _addNewIndex /* newIndex*/, -1 /*oldIndex*/); return newItem; } bool IBindingList.AllowRemove { get { return _viewData.AllowRemove; } } bool IBindingList.SupportsChangeNotification { get { return true; } } bool IBindingList.SupportsSearching { get { return false; } } bool IBindingList.SupportsSorting { get { return false; } } bool IBindingList.IsSorted { get { return false; } } PropertyDescriptor IBindingList.SortProperty { get { throw EntityUtil.NotSupported(); } } ListSortDirection IBindingList.SortDirection { get { throw EntityUtil.NotSupported(); } } public event System.ComponentModel.ListChangedEventHandler ListChanged { add { onListChanged += value; } remove { onListChanged -= value; } } void IBindingList.AddIndex(PropertyDescriptor property) { throw EntityUtil.NotSupported(); } void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction) { throw EntityUtil.NotSupported(); } int IBindingList.Find(PropertyDescriptor property, object key) { throw EntityUtil.NotSupported(); } void IBindingList.RemoveIndex(PropertyDescriptor property) { throw EntityUtil.NotSupported(); } void IBindingList.RemoveSort() { throw EntityUtil.NotSupported(); } #endregion ////// Get item at the specified index. /// /// /// The zero-based index of the element to get or set. /// ////// This strongly-typed indexer is used by the data binding in WebForms and ASP.NET /// to determine the Type of elements in the bound list. /// The list of properties available for binding can then be determined from that element Type. /// public TElement this[int index] { get { return _viewData.List[index]; } set { // this represents a ROW basically whole entity, we should not allow any setting throw EntityUtil.CannotReplacetheEntityorRow(); } } #region IList implementation object IList.this[int index] { get { return _viewData.List[index]; } set { // this represents a ROW basically whole entity, we should not allow any setting throw EntityUtil.CannotReplacetheEntityorRow(); } } bool IList.IsReadOnly { get { return !(_viewData.AllowNew || _viewData.AllowRemove); } } bool IList.IsFixedSize { get { return (false); } } int IList.Add(object value) { EnsureWritableList(); EntityUtil.CheckArgumentNull(value, "value"); if (!(value is TElement)) { throw EntityUtil.IncompatibleArgument(); } ((ICancelAddNew)this).EndNew(_addNewIndex); int index = ((IList)this).IndexOf(value); // Add the item if it doesn't already exist in the binding list. if (index == -1) { index = _viewData.Add((TElement)value, false); // Only fire a change event if the IObjectView data doesn't implicitly fire an event itself. if (!_viewData.FiresEventOnAdd) { _listener.RegisterEntityEvents(value); OnListChanged(ListChangedType.ItemAdded, index /*newIndex*/, -1/* oldIndex*/); } } return index; } void IList.Clear() { EnsureWritableList(); ((ICancelAddNew)this).EndNew(_addNewIndex); // Only fire a change event if the IObjectView data doesn't implicitly fire an event itself. if (_viewData.FiresEventOnClear) { _viewData.Clear(); } else { try { // Suspend list changed events during the clear, since the IObjectViewData declared that it wouldn't fire an event. // It's possible the IObjectViewData could implement Clear by repeatedly calling Remove, // and we don't want these events to percolate during the Clear operation. _suspendEvent = true; _viewData.Clear(); } finally { _suspendEvent = false; } OnListChanged(ListChangedType.Reset, -1 /*newIndex*/, -1/* oldIndex*/); // Indexes not used for reset event. } } bool IList.Contains(object value) { bool itemExists; if (value is TElement) { itemExists = _viewData.List.Contains((TElement)value); } else { itemExists = false; } return itemExists; } int IList.IndexOf(object value) { int index; if (value is TElement) { index = _viewData.List.IndexOf((TElement)value); } else { index = -1; } return index; } void IList.Insert(int index, object value) { throw EntityUtil.IndexBasedInsertIsNotSupported(); } void IList.Remove(object value) { EnsureWritableList(); EntityUtil.CheckArgumentNull(value, "value"); if (!(value is TElement)) { throw EntityUtil.IncompatibleArgument(); } Debug.Assert(((IList)this).Contains(value), "Value does not exist in view."); ((ICancelAddNew)this).EndNew(_addNewIndex); TElement item = (TElement)value; int index = _viewData.List.IndexOf(item); bool removed = _viewData.Remove(item, false); // Only fire a change event if the IObjectView data doesn't implicitly fire an event itself. if (removed && !_viewData.FiresEventOnRemove) { _listener.UnregisterEntityEvents(item); OnListChanged(ListChangedType.ItemDeleted, index /* newIndex */, -1 /* oldIndex */); } } void IList.RemoveAt(int index) { ((IList)this).Remove(((IList)this)[index]); } #endregion #region ICollection implementation public int Count { get { return _viewData.List.Count; } } public void CopyTo(Array array, int index) { ((IList)_viewData.List).CopyTo(array, index); } object ICollection.SyncRoot { get { return this; } } bool ICollection.IsSynchronized { get { return false; } } public IEnumerator GetEnumerator() { return _viewData.List.GetEnumerator(); } #endregion private void OnListChanged(ListChangedType listchangedType, int newIndex, int oldIndex) { ListChangedEventArgs changeArgs = new ListChangedEventArgs(listchangedType, newIndex, oldIndex); OnListChanged(changeArgs); } private void OnListChanged(ListChangedEventArgs changeArgs) { // Only fire the event if someone listens to it and it is not suspended. if (onListChanged != null && !_suspendEvent) { onListChanged(this, changeArgs); } } void IObjectView.EntityPropertyChanged(object sender, PropertyChangedEventArgs e) { Debug.Assert(sender is TElement, "Entity should be of type TElement"); int index = ((IList)this).IndexOf((TElement)sender); OnListChanged(ListChangedType.ItemChanged, index /*newIndex*/, index/*oldIndex*/); } ////// Handle a change in the underlying collection bound by this ObjectView. /// /// The source of the event. /// /// Event arguments that specify the type of modification and the associated item. /// void IObjectView.CollectionChanged(object sender, CollectionChangeEventArgs e) { // If there is a pending edit of a new item in the bound list (indicated by _addNewIndex >= 0) // and the collection membership changed due to an operation external to this ObjectView, // it is possible that the _addNewIndex position will need to be adjusted. // // If the modification was made through this ObjectView, the pending edit would have been implicitly committed, // and there would be no need to examine it here. TElement addNew = default(TElement); if (_addNewIndex >= 0) { addNew = this[_addNewIndex]; } ListChangedEventArgs changeArgs = _viewData.OnCollectionChanged(sender, e, _listener); if (_addNewIndex >= 0) { if (_addNewIndex >= this.Count) { _addNewIndex = ((IList)this).IndexOf(addNew); } else if (!this[_addNewIndex].Equals(addNew)) { _addNewIndex = ((IList)this).IndexOf(addNew); } } if (changeArgs != null) { OnListChanged(changeArgs); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
![Network programming in C#, Network Programming in VB.NET, Network Programming in .NET](/images/book.jpg)
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CheckBox.cs
- ExceptionHandler.cs
- SimpleType.cs
- FormViewCommandEventArgs.cs
- GrabHandleGlyph.cs
- SlipBehavior.cs
- SchemaAttDef.cs
- MeshGeometry3D.cs
- CheckBox.cs
- ProxyWebPartManager.cs
- WebErrorHandler.cs
- ExpressionPrinter.cs
- CalendarDataBindingHandler.cs
- Psha1DerivedKeyGenerator.cs
- ImportContext.cs
- FlowDocumentPage.cs
- AssociationEndMember.cs
- ComponentEditorPage.cs
- UdpContractFilterBehavior.cs
- InvalidCastException.cs
- WebPartZoneBase.cs
- DNS.cs
- SpotLight.cs
- ControlUtil.cs
- RequestCache.cs
- EncodingDataItem.cs
- ReliableMessagingHelpers.cs
- FaultException.cs
- GeneralTransformGroup.cs
- FamilyMapCollection.cs
- SoapMessage.cs
- SizeConverter.cs
- FocusTracker.cs
- CheckoutException.cs
- EllipseGeometry.cs
- IBuiltInEvidence.cs
- mediaeventshelper.cs
- HtmlFormWrapper.cs
- SqlCacheDependency.cs
- WebServiceClientProxyGenerator.cs
- WebServicesDescriptionAttribute.cs
- HeaderUtility.cs
- Claim.cs
- StateChangeEvent.cs
- XmlWriterSettings.cs
- WorkflowWebService.cs
- SID.cs
- AsyncStreamReader.cs
- ISessionStateStore.cs
- XhtmlBasicObjectListAdapter.cs
- HTTPNotFoundHandler.cs
- XmlCharacterData.cs
- LinqMaximalSubtreeNominator.cs
- ThreadStartException.cs
- WebPermission.cs
- LightweightCodeGenerator.cs
- QilScopedVisitor.cs
- AddInStore.cs
- Module.cs
- FrameworkRichTextComposition.cs
- WindowVisualStateTracker.cs
- DataFieldConverter.cs
- BamlLocalizer.cs
- MD5.cs
- QueryPrefixOp.cs
- AppSettingsSection.cs
- CreatingCookieEventArgs.cs
- DataPagerFieldCommandEventArgs.cs
- EdgeModeValidation.cs
- Transform.cs
- KeyPressEvent.cs
- SkinBuilder.cs
- StubHelpers.cs
- AutoResetEvent.cs
- EntityCollection.cs
- CaseInsensitiveHashCodeProvider.cs
- DataPointer.cs
- AuthenticationService.cs
- TargetInvocationException.cs
- ApplicationTrust.cs
- ScriptResourceInfo.cs
- RegexReplacement.cs
- StringUtil.cs
- PerformanceCounterCategory.cs
- TextEndOfLine.cs
- UnknownBitmapEncoder.cs
- AccessDataSourceWizardForm.cs
- IntegrationExceptionEventArgs.cs
- BitmapImage.cs
- MultilineStringEditor.cs
- XPathNode.cs
- BypassElement.cs
- ReadingWritingEntityEventArgs.cs
- BinaryObjectInfo.cs
- RowSpanVector.cs
- InlineUIContainer.cs
- DataContext.cs
- SplitterCancelEvent.cs
- CompressedStack.cs
- AsyncStreamReader.cs