Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / GridViewColumnCollection.cs / 1305600 / GridViewColumnCollection.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System.Collections.Generic; // Listusing System.Collections.ObjectModel; // ObservableCollection using System.Collections.Specialized; // NotifyCollectionChangedEventHandler using System.ComponentModel; // DesignerSerializationVisibility using System.Diagnostics; // Debug using System.Windows.Data; // Binding.IndexerName using MS.Internal; // Helper namespace System.Windows.Controls { /// /// a List of GridViewColumn. Cooperating with GridViewRowPresenter, can insert and remove column.efficiently. /// [Serializable()] public class GridViewColumnCollection : ObservableCollection{ //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- //------------------------------------------------------ // // Public Methods / Event // //----------------------------------------------------- //------------------------------------------------------ // // Protected Methods // //------------------------------------------------------ #region Protected Methods /// /// called by base class ObservableCollection<T> when the list is being cleared; /// GridViewColumnCollection override this method to do some internal preprocess work /// protected override void ClearItems() { VerifyAccess(); _internalEventArg = ClearPreprocess(); base.ClearItems(); } ////// called by base class ObservableCollection<T> when an column is removed from list; /// GridViewColumnCollection override this method to do some internal preprocess work /// protected override void RemoveItem(int index) { VerifyAccess(); _internalEventArg = RemoveAtPreprocess(index); base.RemoveItem(index); } ////// called by base class ObservableCollection<T> when an item is added to list; /// GridViewColumnCollection override this method to do some internal preprocess work /// protected override void InsertItem(int index, GridViewColumn column) { VerifyAccess(); _internalEventArg = InsertPreprocess(index, column); base.InsertItem(index, column); } ////// called by base class ObservableCollection<T> when an column is set in list; /// GridViewColumnCollection override this method to do some internal preprocess work /// protected override void SetItem(int index, GridViewColumn column) { VerifyAccess(); _internalEventArg = SetPreprocess(index, column); if (_internalEventArg != null) // the new column is equals to the old one. { base.SetItem(index, column); } } ////// Move column to a different index /// /// index of the column which is being moved /// index of the column to be move to protected override void MoveItem(int oldIndex, int newIndex) { if (oldIndex != newIndex) { VerifyAccess(); _internalEventArg = MovePreprocess(oldIndex, newIndex); base.MoveItem(oldIndex, newIndex); } } // Override OnCollectionChanged method to ensure InternalCollectionChanged event is raised before public one. #region OnCollectionChanged ////// raise CollectionChanged event to any listeners /// protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { OnInternalCollectionChanged(); base.OnCollectionChanged(e); } #endregion OnCollectionChanged #endregion //----------------------------------------------------- // // Internal Methods / Properties // //------------------------------------------------------ #region Internal Methods / Properties internal event NotifyCollectionChangedEventHandler InternalCollectionChanged { add { _internalCollectionChanged += value; } remove { _internalCollectionChanged -= value; } } ////// Make the collection not changabel. /// Should call UnblockWrite the same times as BlockWrite to make collection writable. /// internal void BlockWrite() { Debug.Assert(IsImmutable != true, "IsImmutable is true before BlockWrite"); IsImmutable = true; } ////// Counterfact the effect of BlockWrite() - restore collection to a changable state. /// internal void UnblockWrite() { Debug.Assert(IsImmutable != false, "IsImmutable is flase before UnblockWrite"); IsImmutable = false; } // Column list. Columns in this list are organized in the order // that they were inserted into this collection. So Move operation // won't change this list. internal ListColumnCollection { get { return _columns; } } // Actual index list of GridViewColumn in ColumnCollection // this[i] == ColumnCollection[IndexList[i]] internal List IndexList { get { return _actualIndices; } } #endregion #region InheritanceContext // The GridView that we're in internal DependencyObject Owner { get { return _owner; } set { if (value != _owner) { if (value == null) { foreach (GridViewColumn c in _columns) { InheritanceContextHelper.RemoveContextFromObject(_owner, c); } } else { foreach (GridViewColumn c in _columns) { InheritanceContextHelper.ProvideContextForObject(value, c); } } _owner = value; } } } // The GridView that we're in [NonSerializedAttribute] private DependencyObject _owner = null; // the Owner is GridView internal bool InViewMode { get { return _inViewMode; } set { _inViewMode = value; } } private bool _inViewMode; #endregion InheritanceContext //----------------------------------------------------- // // Private Methods // //----------------------------------------------------- #region Private Methods private void OnInternalCollectionChanged() { if (_internalCollectionChanged != null && _internalEventArg != null) { _internalCollectionChanged(this, _internalEventArg); // This class member is used as parameter, so clear it after used. // For details, see definition. _internalEventArg = null; } } private void ColumnPropertyChanged(object sender, PropertyChangedEventArgs e) { GridViewColumn column = sender as GridViewColumn; if (_internalCollectionChanged != null && column != null) { _internalCollectionChanged(this, new GridViewColumnCollectionChangedEventArgs(column, e.PropertyName)); } } private GridViewColumnCollectionChangedEventArgs MovePreprocess(int oldIndex, int newIndex) { Debug.Assert(oldIndex != newIndex, "oldIndex==newIndex when perform move action."); VerifyIndexInRange(oldIndex, "oldIndex"); VerifyIndexInRange(newIndex, "newIndex"); int actualIndex = _actualIndices[oldIndex]; if (oldIndex < newIndex) { for (int targetIndex = oldIndex; targetIndex < newIndex; targetIndex++) { _actualIndices[targetIndex] = _actualIndices[targetIndex + 1]; } } else //if (oldIndex > newIndex) { for (int targetIndex = oldIndex; targetIndex > newIndex; targetIndex--) { _actualIndices[targetIndex] = _actualIndices[targetIndex - 1]; } } _actualIndices[newIndex] = actualIndex; return new GridViewColumnCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, _columns[actualIndex], newIndex, oldIndex, actualIndex); } private GridViewColumnCollectionChangedEventArgs ClearPreprocess() { GridViewColumn[] list = new GridViewColumn[Count]; if (Count > 0) { CopyTo(list, 0); } // reset columns *before* remove foreach (GridViewColumn c in _columns) { c.ResetPrivateData(); ((INotifyPropertyChanged)c).PropertyChanged -= new PropertyChangedEventHandler(ColumnPropertyChanged); InheritanceContextHelper.RemoveContextFromObject(_owner, c); } _columns.Clear(); _actualIndices.Clear(); return new GridViewColumnCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, list); } private GridViewColumnCollectionChangedEventArgs RemoveAtPreprocess(int index) { VerifyIndexInRange(index, "index"); int actualIndex = _actualIndices[index]; GridViewColumn column = _columns[actualIndex]; column.ResetPrivateData(); ((INotifyPropertyChanged)column).PropertyChanged -= new PropertyChangedEventHandler(ColumnPropertyChanged); _columns.RemoveAt(actualIndex); UpdateIndexList(actualIndex, index); UpdateActualIndexInColumn(actualIndex); InheritanceContextHelper.RemoveContextFromObject(_owner, column); return new GridViewColumnCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, column, index, actualIndex); } // Remove the index of the removed column in _actualIndices // Correct index in _actualIndices which is bigger than actualIndex private void UpdateIndexList(int actualIndex, int index) { for (int sourceIndex = 0; sourceIndex < index; sourceIndex++) { int i = _actualIndices[sourceIndex]; if (i > actualIndex) { _actualIndices[sourceIndex] = i - 1; } } for (int sourceIndex = index + 1; sourceIndex < _actualIndices.Count; sourceIndex++) { int i = _actualIndices[sourceIndex]; if (i < actualIndex) { _actualIndices[sourceIndex - 1] = i; } else if (i > actualIndex) { _actualIndices[sourceIndex - 1] = i - 1; } } _actualIndices.RemoveAt(_actualIndices.Count - 1); } // pack the actual indeices in columns from after the removed one private void UpdateActualIndexInColumn(int iStart) { for (int i = iStart; i < _columns.Count; i++) { _columns[i].ActualIndex = i; } } private GridViewColumnCollectionChangedEventArgs InsertPreprocess(int index, GridViewColumn column) { int count = _columns.Count; if (index < 0 || index > count) { throw new ArgumentOutOfRangeException("index"); } ValidateColumnForInsert(column); _columns.Add(column); column.ActualIndex = count; _actualIndices.Insert(index, count); // // NOTE: // // To prevent a useless (if not error prone) event from being fired, we need to call // {ProvideContextForObject()} before {column.PropertyChanged += ...}. // // Below is the case when a column property change event can be fired before the event // that this column was added into the collection. // // 1. add a new column to the ColumnCollection, e.g. // // // // 2. once column is connected to the collection, DynamicResource will start loading // the template // // 3. #1 will trigger a collection change event which will be fired when this method // is accomplished. // // 4. #2 will trigger a property change event which will be fired at the middle of this // method. // // Ultimately, RowPresenter will receive both #3 and #4. But from above, #4 will come // before #3. Therefore #4 is totally useless because #3 is unknown yet. // InheritanceContextHelper.ProvideContextForObject(_owner, column); ((INotifyPropertyChanged)column).PropertyChanged += new PropertyChangedEventHandler(ColumnPropertyChanged); return new GridViewColumnCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, column, index, count /* actual index*/); } // This[index] = newColumn private GridViewColumnCollectionChangedEventArgs SetPreprocess(int index, GridViewColumn newColumn) { VerifyIndexInRange(index, "index"); GridViewColumn oldColumn = this[index]; if (oldColumn != newColumn) { int oldColumnActualIndex = _actualIndices[index]; RemoveAtPreprocess(index); InsertPreprocess(index, newColumn); // NOTE: Insert Preprocess already updated InheritanceContext. // Don't update here again. return new GridViewColumnCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newColumn, oldColumn, index, oldColumnActualIndex); } return null; } private void VerifyIndexInRange(int index, string indexName) { if (index < 0 || index >= _actualIndices.Count) { throw new ArgumentOutOfRangeException(indexName); } } // Throw if column is null or already existed in a GVCC private void ValidateColumnForInsert(GridViewColumn column) { if (column == null) { throw new ArgumentNullException("column"); } if (column.ActualIndex >= 0) { throw new InvalidOperationException(SR.Get(SRID.ListView_NotAllowShareColumnToTwoColumnCollection)); } } private void VerifyAccess() { if (IsImmutable) { throw new InvalidOperationException(SR.Get(SRID.ListView_GridViewColumnCollectionIsReadOnly)); } // Although CheckReentrancy() is called in base class, we still need to call it here again, // otherwise, when Reentrancy is found and exception is thrown, our operation is done and can't be undo. CheckReentrancy(); } #endregion //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ #region Private Fields // internal storage of CollumnCollection private List _columns = new List (); // index of column in _columns // GridViewColumn this[i] in public interface is _columns[_actualIndices[i]] private List _actualIndices = new List (); // GridViewHeaderRowPresenter will set this field to true once reorder is started. private bool IsImmutable { get { return _isImmutable; } set { _isImmutable = value; } } private bool _isImmutable; private event NotifyCollectionChangedEventHandler _internalCollectionChanged; // EventArgs for _internalCollectionChanged event. // We should raise internal event just before ColletonChanged event of base class, // but can't pass this to OnCollectionChanged method as parameter. So store it as a class member. [NonSerialized] private GridViewColumnCollectionChangedEventArgs _internalEventArg; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WindowsProgressbar.cs
- ThrowHelper.cs
- HwndProxyElementProvider.cs
- Brush.cs
- XsdValidatingReader.cs
- DecimalFormatter.cs
- ActivationArguments.cs
- DisplayNameAttribute.cs
- WebPartConnectionsConfigureVerb.cs
- LayoutExceptionEventArgs.cs
- Html32TextWriter.cs
- DynamicValueConverter.cs
- safemediahandle.cs
- Operators.cs
- XmlObjectSerializerWriteContextComplexJson.cs
- BitArray.cs
- Brush.cs
- AssemblyName.cs
- WebPartTransformerCollection.cs
- OutOfMemoryException.cs
- SqlNodeTypeOperators.cs
- DataGridViewColumnConverter.cs
- CheckBoxPopupAdapter.cs
- HttpConfigurationSystem.cs
- NavigationProperty.cs
- ReferenceList.cs
- NotificationContext.cs
- RepeatBehaviorConverter.cs
- ProviderSettingsCollection.cs
- Command.cs
- FileSystemEventArgs.cs
- NoneExcludedImageIndexConverter.cs
- Rights.cs
- ConfigXmlElement.cs
- DbFunctionCommandTree.cs
- XmlDocumentType.cs
- Page.cs
- DurableEnlistmentState.cs
- CalendarTable.cs
- ADMembershipProvider.cs
- ByteStream.cs
- ProofTokenCryptoHandle.cs
- ConnectionManagementSection.cs
- XamlSerializationHelper.cs
- IsolatedStorageFileStream.cs
- XmlEnumAttribute.cs
- ConfigurationManager.cs
- GeneralTransformGroup.cs
- RankException.cs
- TextBox.cs
- UserControlParser.cs
- entityreference_tresulttype.cs
- XmlQueryCardinality.cs
- WindowsRebar.cs
- HtmlMeta.cs
- SchemaObjectWriter.cs
- SchemaNotation.cs
- CustomAttributeFormatException.cs
- _NestedMultipleAsyncResult.cs
- DefaultBindingPropertyAttribute.cs
- DialogDivider.cs
- UrlRoutingHandler.cs
- IdleTimeoutMonitor.cs
- GradientPanel.cs
- WebPartCatalogCloseVerb.cs
- ValuePattern.cs
- HttpBrowserCapabilitiesWrapper.cs
- SqlGenerator.cs
- DefaultBinder.cs
- XmlIncludeAttribute.cs
- OdbcPermission.cs
- XmlChildEnumerator.cs
- BitmapCache.cs
- CurrencyWrapper.cs
- KeyedByTypeCollection.cs
- AppDomainEvidenceFactory.cs
- ExceptionWrapper.cs
- TypeUnloadedException.cs
- TextSchema.cs
- ActiveXHelper.cs
- CompModSwitches.cs
- mediaeventshelper.cs
- MetadataCache.cs
- SerialPort.cs
- LinkClickEvent.cs
- ValueUtilsSmi.cs
- SolidBrush.cs
- InplaceBitmapMetadataWriter.cs
- EventManager.cs
- LinqDataView.cs
- DictionarySectionHandler.cs
- ImageKeyConverter.cs
- BooleanFacetDescriptionElement.cs
- AssemblyHash.cs
- PackagePartCollection.cs
- Coordinator.cs
- HttpsHostedTransportConfiguration.cs
- GregorianCalendarHelper.cs
- Input.cs
- CodeExpressionStatement.cs