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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Deflater.cs
- ProfileBuildProvider.cs
- XmlLoader.cs
- AttributeUsageAttribute.cs
- TextBoxAutomationPeer.cs
- DataView.cs
- EncryptedXml.cs
- SamlAuthorizationDecisionStatement.cs
- SyndicationDeserializer.cs
- Point3DAnimation.cs
- SBCSCodePageEncoding.cs
- ButtonChrome.cs
- DispatcherExceptionFilterEventArgs.cs
- Menu.cs
- EmptyArray.cs
- WebProxyScriptElement.cs
- WebPartVerbCollection.cs
- LicenseContext.cs
- MethodBody.cs
- PersonalizablePropertyEntry.cs
- XmlSerializationReader.cs
- LinqDataSourceSelectEventArgs.cs
- DesignerDataTableBase.cs
- ProtectedConfigurationSection.cs
- SizeAnimationBase.cs
- SqlDataSourceParameterParser.cs
- UniqueConstraint.cs
- CheckBox.cs
- WebBrowserSiteBase.cs
- InstancePersistence.cs
- BindingBase.cs
- HandlerBase.cs
- EventData.cs
- FormatterConverter.cs
- TextLineResult.cs
- OpacityConverter.cs
- ProfileBuildProvider.cs
- DocumentViewer.cs
- DesignerValidationSummaryAdapter.cs
- _FtpControlStream.cs
- WebBrowser.cs
- DbCommandDefinition.cs
- XmlSchemaSearchPattern.cs
- recordstate.cs
- FeatureAttribute.cs
- PolyLineSegmentFigureLogic.cs
- CuspData.cs
- SqlWebEventProvider.cs
- DataSourceCache.cs
- CodeTypeReference.cs
- OleDbErrorCollection.cs
- IsolatedStorageFile.cs
- ConfigXmlComment.cs
- EntityClassGenerator.cs
- SymmetricKey.cs
- PassportIdentity.cs
- GeneralTransform3DTo2D.cs
- TextFormatterContext.cs
- TransportSecurityProtocolFactory.cs
- StandardOleMarshalObject.cs
- StringArrayConverter.cs
- DomainUpDown.cs
- SchemaNamespaceManager.cs
- ClientSponsor.cs
- QuaternionKeyFrameCollection.cs
- TextTreeTextBlock.cs
- DataQuery.cs
- RuleConditionDialog.Designer.cs
- TextTreeDeleteContentUndoUnit.cs
- WorkflowRuntimeServiceElementCollection.cs
- SqlNode.cs
- DbgUtil.cs
- DataGridTablesFactory.cs
- DoubleLinkList.cs
- ProcessInfo.cs
- Resources.Designer.cs
- IOThreadScheduler.cs
- DefaultAssemblyResolver.cs
- HwndHostAutomationPeer.cs
- TreeNodeCollection.cs
- ListViewUpdatedEventArgs.cs
- Win32Exception.cs
- InfiniteTimeSpanConverter.cs
- fixedPageContentExtractor.cs
- DecimalSumAggregationOperator.cs
- BufferBuilder.cs
- AsyncPostBackTrigger.cs
- ReadOnlyDataSource.cs
- XmlSchemaValidationException.cs
- MethodCallTranslator.cs
- Splitter.cs
- ContentPropertyAttribute.cs
- RestClientProxyHandler.cs
- MenuItemBinding.cs
- BindingMemberInfo.cs
- PublisherMembershipCondition.cs
- MessageSecurityOverHttp.cs
- ColumnCollection.cs
- UserMapPath.cs
- CroppedBitmap.cs