Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / Primitives / GridViewRowPresenterBase.cs / 1305600 / GridViewRowPresenterBase.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System.Collections; // IEnumerator using System.Collections.Generic; // Listusing System.Collections.Specialized; // NotifyCollectionChangedEventHandler using System.Collections.ObjectModel; // Collection using System.ComponentModel; // PropertyChangedEventArgs using System.Diagnostics; // Debug using System.Windows.Media; // VisualOperations using MS.Internal.Controls; // EmptyEnumerator namespace System.Windows.Controls.Primitives { /// /// Base class for GridViewfRowPresenter and HeaderRowPresenter. /// public abstract class GridViewRowPresenterBase : FrameworkElement, IWeakEventListener { //------------------------------------------------------------------- // // Public Methods // //------------------------------------------------------------------- #region Public Methods ////// Returns a string representation of this object. /// ///public override string ToString() { return SR.Get(SRID.ToStringFormatString_GridViewRowPresenterBase, this.GetType(), (Columns != null) ? Columns.Count : 0); } #endregion //-------------------------------------------------------------------- // // Public Properties // //------------------------------------------------------------------- #region Public Properties /// /// Columns DependencyProperty /// public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register( "Columns", typeof(GridViewColumnCollection), typeof(GridViewRowPresenterBase), new FrameworkPropertyMetadata( (GridViewColumnCollection)null /* default value */, FrameworkPropertyMetadataOptions.AffectsMeasure, new PropertyChangedCallback(ColumnsPropertyChanged)) ); ////// Columns Property /// public GridViewColumnCollection Columns { get { return (GridViewColumnCollection)GetValue(ColumnsProperty); } set { SetValue(ColumnsProperty, value); } } #endregion //-------------------------------------------------------------------- // // Protected Methods / Properties // //-------------------------------------------------------------------- #region Protected Methods / Properties ////// Returns enumerator to logical children. /// protected internal override IEnumerator LogicalChildren { get { if (InternalChildren.Count == 0) { // empty GridViewRowPresenterBase has *no* logical children; give empty enumerator return EmptyEnumerator.Instance; } // otherwise, its logical children is its visual children return InternalChildren.GetEnumerator(); } } ////// Gets the Visual children count. /// protected override int VisualChildrenCount { get { if (_uiElementCollection == null) { return 0; } else { return _uiElementCollection.Count; } } } ////// Gets the Visual child at the specified index. /// protected override Visual GetVisualChild(int index) { if (_uiElementCollection == null) { throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); } return _uiElementCollection[index]; } #endregion //------------------------------------------------------------------- // // Internal Methods / Properties // //-------------------------------------------------------------------- #region Internal Methods ////// process the column collection chagned event /// internal virtual void OnColumnCollectionChanged(GridViewColumnCollectionChangedEventArgs e) { if (DesiredWidthList != null) { if (e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace) { // NOTE: The steps to make DesiredWidthList.Count <= e.ActualIndex // // 1. init with 3 auto columns; // 2. add 1 column to the column collection with width 90.0; // 3. remove the column we jsut added to the the collection; // // Now we have DesiredWidthList.Count equals to 3 while the removed column // has ActualIndex equals to 3. // if (DesiredWidthList.Count > e.ActualIndex) { DesiredWidthList.RemoveAt(e.ActualIndex); } } else if (e.Action == NotifyCollectionChangedAction.Reset) { DesiredWidthList = null; } } } ////// process the column property chagned event /// internal abstract void OnColumnPropertyChanged(GridViewColumn column, string propertyName); ////// ensure ShareStateList have at least columns.Count items /// internal void EnsureDesiredWidthList() { GridViewColumnCollection columns = Columns; if (columns != null) { int count = columns.Count; if (DesiredWidthList == null) { DesiredWidthList = new List(count); } int c = count - DesiredWidthList.Count; for (int i = 0; i < c; i++) { DesiredWidthList.Add(Double.NaN); } } } /// /// list of currently reached max value of DesiredWidth of cell in the column /// internal ListDesiredWidthList { get { return _desiredWidthList; } private set { _desiredWidthList = value; } } /// /// if visual tree is out of date /// internal bool NeedUpdateVisualTree { get { return _needUpdateVisualTree; } set { _needUpdateVisualTree = value; } } ////// collection if children /// internal UIElementCollection InternalChildren { get { if (_uiElementCollection == null) //nobody used it yet { _uiElementCollection = new UIElementCollection(this /* visual parent */, this /* logical parent */); } return _uiElementCollection; } } // the minimum width for dummy header when measure internal const double c_PaddingHeaderMinWidth = 2.0; #endregion //------------------------------------------------------------------- // // Private Methods / Properties / Fields // //------------------------------------------------------------------- #region Private Methods / Properties / Fields // Property invalidation callback invoked when ColumnCollectionProperty is invalidated private static void ColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { GridViewRowPresenterBase c = (GridViewRowPresenterBase)d; GridViewColumnCollection oldCollection = (GridViewColumnCollection)e.OldValue; if (oldCollection != null) { InternalCollectionChangedEventManager.RemoveListener(oldCollection, c); // NOTE: // If the collection is NOT in view mode (a.k.a owner isn't GridView), // RowPresenter is responsible to be or to find one to be the collection's mentor. // if (!oldCollection.InViewMode && oldCollection.Owner == c.GetStableAncester()) { oldCollection.Owner = null; } } GridViewColumnCollection newCollection = (GridViewColumnCollection)e.NewValue; if (newCollection != null) { InternalCollectionChangedEventManager.AddListener(newCollection, c); // Similar to what we do to oldCollection. But, of course, in a reverse way. if (!newCollection.InViewMode && newCollection.Owner == null) { newCollection.Owner = c.GetStableAncester(); } } c.NeedUpdateVisualTree = true; c.InvalidateMeasure(); } // // NOTE: // // If the collection is NOT in view mode, RowPresenter should be mentor of the Collection. // But if presenter + collection are used to restyle ListBoxItems and the ItemsPanel is // VSP, there are 2 problems: // // 1. each RowPresenter want to be the mentor, too many context change event // 2. when doing scroll, VSP will dispose those LB items which are out of view. But they // are still referenced by the Collecion (at the Owner property) - memory leak. // // Solution: // If RowPresenter is inside an ItemsControl (IC\LB\CB), use the ItemsControl as the // mentor. Therefore, // - context change is minimized because ItemsControl for different items is the same; // - no memory leak because when viturlizing, only dispose items not the IC itself. // private FrameworkElement GetStableAncester() { ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(TemplatedParent); return (ic != null) ? ic : (FrameworkElement)this; } // if and only if both conditions below are satisfied, row presenter visual is ready. // 1. is initialized, which ensures RowPresenter is created // 2. !NeedUpdateVisualTree, which ensures all visual elements generated by RowPresenter are created private bool IsPresenterVisualReady { get { return (IsInitialized && !NeedUpdateVisualTree); } } ////// Handle events from the centralized event table /// bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs args) { if (managerType == typeof(InternalCollectionChangedEventManager)) { ColumnCollectionChanged(sender, (NotifyCollectionChangedEventArgs)args); } else { return false; // unrecognized event } return true; } ////// Handler of GridViewColumnCollection.CollectionChanged event. /// private void ColumnCollectionChanged(object sender, NotifyCollectionChangedEventArgs arg) { GridViewColumnCollectionChangedEventArgs e = arg as GridViewColumnCollectionChangedEventArgs; if (e != null && IsPresenterVisualReady)// if and only if rowpresenter's visual is ready, shall rowpresenter go ahead process the event. { // Property of one column changed if (e.Column != null) { OnColumnPropertyChanged(e.Column, e.PropertyName); } else { OnColumnCollectionChanged(e); } } } private UIElementCollection _uiElementCollection; private bool _needUpdateVisualTree = true; private List_desiredWidthList; #endregion } /// /// Manager for the GridViewColumnCollection.CollectionChanged event. /// internal class InternalCollectionChangedEventManager : WeakEventManager { #region Constructors // // Constructors // private InternalCollectionChangedEventManager() { } #endregion Constructors #region Public Methods // // Public Methods // ////// Add a listener to the given source's event. /// public static void AddListener(GridViewColumnCollection source, IWeakEventListener listener) { if (source == null) throw new ArgumentNullException("source"); if (listener == null) throw new ArgumentNullException("listener"); CurrentManager.ProtectedAddListener(source, listener); } ////// Remove a listener to the given source's event. /// public static void RemoveListener(GridViewColumnCollection source, IWeakEventListener listener) { if (source == null) throw new ArgumentNullException("source"); if (listener == null) throw new ArgumentNullException("listener"); CurrentManager.ProtectedRemoveListener(source, listener); } #endregion Public Methods #region Protected Methods // // Protected Methods // ////// Listen to the given source for the event. /// protected override void StartListening(object source) { GridViewColumnCollection typedSource = (GridViewColumnCollection)source; typedSource.InternalCollectionChanged += new NotifyCollectionChangedEventHandler(OnCollectionChanged); } ////// Stop listening to the given source for the event. /// protected override void StopListening(object source) { GridViewColumnCollection typedSource = (GridViewColumnCollection)source; typedSource.InternalCollectionChanged -= new NotifyCollectionChangedEventHandler(OnCollectionChanged); } #endregion Protected Methods #region Private Properties // // Private Properties // // get the event manager for the current thread private static InternalCollectionChangedEventManager CurrentManager { get { Type managerType = typeof(InternalCollectionChangedEventManager); InternalCollectionChangedEventManager manager = (InternalCollectionChangedEventManager)GetCurrentManager(managerType); // at first use, create and register a new manager if (manager == null) { manager = new InternalCollectionChangedEventManager(); SetCurrentManager(managerType, manager); } return manager; } } #endregion Private Properties #region Private Methods // // Private Methods // // event handler for CollectionChanged event private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { DeliverEvent(sender, args); } #endregion Private Methods } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System.Collections; // IEnumerator using System.Collections.Generic; // Listusing System.Collections.Specialized; // NotifyCollectionChangedEventHandler using System.Collections.ObjectModel; // Collection using System.ComponentModel; // PropertyChangedEventArgs using System.Diagnostics; // Debug using System.Windows.Media; // VisualOperations using MS.Internal.Controls; // EmptyEnumerator namespace System.Windows.Controls.Primitives { /// /// Base class for GridViewfRowPresenter and HeaderRowPresenter. /// public abstract class GridViewRowPresenterBase : FrameworkElement, IWeakEventListener { //------------------------------------------------------------------- // // Public Methods // //------------------------------------------------------------------- #region Public Methods ////// Returns a string representation of this object. /// ///public override string ToString() { return SR.Get(SRID.ToStringFormatString_GridViewRowPresenterBase, this.GetType(), (Columns != null) ? Columns.Count : 0); } #endregion //-------------------------------------------------------------------- // // Public Properties // //------------------------------------------------------------------- #region Public Properties /// /// Columns DependencyProperty /// public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register( "Columns", typeof(GridViewColumnCollection), typeof(GridViewRowPresenterBase), new FrameworkPropertyMetadata( (GridViewColumnCollection)null /* default value */, FrameworkPropertyMetadataOptions.AffectsMeasure, new PropertyChangedCallback(ColumnsPropertyChanged)) ); ////// Columns Property /// public GridViewColumnCollection Columns { get { return (GridViewColumnCollection)GetValue(ColumnsProperty); } set { SetValue(ColumnsProperty, value); } } #endregion //-------------------------------------------------------------------- // // Protected Methods / Properties // //-------------------------------------------------------------------- #region Protected Methods / Properties ////// Returns enumerator to logical children. /// protected internal override IEnumerator LogicalChildren { get { if (InternalChildren.Count == 0) { // empty GridViewRowPresenterBase has *no* logical children; give empty enumerator return EmptyEnumerator.Instance; } // otherwise, its logical children is its visual children return InternalChildren.GetEnumerator(); } } ////// Gets the Visual children count. /// protected override int VisualChildrenCount { get { if (_uiElementCollection == null) { return 0; } else { return _uiElementCollection.Count; } } } ////// Gets the Visual child at the specified index. /// protected override Visual GetVisualChild(int index) { if (_uiElementCollection == null) { throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange)); } return _uiElementCollection[index]; } #endregion //------------------------------------------------------------------- // // Internal Methods / Properties // //-------------------------------------------------------------------- #region Internal Methods ////// process the column collection chagned event /// internal virtual void OnColumnCollectionChanged(GridViewColumnCollectionChangedEventArgs e) { if (DesiredWidthList != null) { if (e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace) { // NOTE: The steps to make DesiredWidthList.Count <= e.ActualIndex // // 1. init with 3 auto columns; // 2. add 1 column to the column collection with width 90.0; // 3. remove the column we jsut added to the the collection; // // Now we have DesiredWidthList.Count equals to 3 while the removed column // has ActualIndex equals to 3. // if (DesiredWidthList.Count > e.ActualIndex) { DesiredWidthList.RemoveAt(e.ActualIndex); } } else if (e.Action == NotifyCollectionChangedAction.Reset) { DesiredWidthList = null; } } } ////// process the column property chagned event /// internal abstract void OnColumnPropertyChanged(GridViewColumn column, string propertyName); ////// ensure ShareStateList have at least columns.Count items /// internal void EnsureDesiredWidthList() { GridViewColumnCollection columns = Columns; if (columns != null) { int count = columns.Count; if (DesiredWidthList == null) { DesiredWidthList = new List(count); } int c = count - DesiredWidthList.Count; for (int i = 0; i < c; i++) { DesiredWidthList.Add(Double.NaN); } } } /// /// list of currently reached max value of DesiredWidth of cell in the column /// internal ListDesiredWidthList { get { return _desiredWidthList; } private set { _desiredWidthList = value; } } /// /// if visual tree is out of date /// internal bool NeedUpdateVisualTree { get { return _needUpdateVisualTree; } set { _needUpdateVisualTree = value; } } ////// collection if children /// internal UIElementCollection InternalChildren { get { if (_uiElementCollection == null) //nobody used it yet { _uiElementCollection = new UIElementCollection(this /* visual parent */, this /* logical parent */); } return _uiElementCollection; } } // the minimum width for dummy header when measure internal const double c_PaddingHeaderMinWidth = 2.0; #endregion //------------------------------------------------------------------- // // Private Methods / Properties / Fields // //------------------------------------------------------------------- #region Private Methods / Properties / Fields // Property invalidation callback invoked when ColumnCollectionProperty is invalidated private static void ColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { GridViewRowPresenterBase c = (GridViewRowPresenterBase)d; GridViewColumnCollection oldCollection = (GridViewColumnCollection)e.OldValue; if (oldCollection != null) { InternalCollectionChangedEventManager.RemoveListener(oldCollection, c); // NOTE: // If the collection is NOT in view mode (a.k.a owner isn't GridView), // RowPresenter is responsible to be or to find one to be the collection's mentor. // if (!oldCollection.InViewMode && oldCollection.Owner == c.GetStableAncester()) { oldCollection.Owner = null; } } GridViewColumnCollection newCollection = (GridViewColumnCollection)e.NewValue; if (newCollection != null) { InternalCollectionChangedEventManager.AddListener(newCollection, c); // Similar to what we do to oldCollection. But, of course, in a reverse way. if (!newCollection.InViewMode && newCollection.Owner == null) { newCollection.Owner = c.GetStableAncester(); } } c.NeedUpdateVisualTree = true; c.InvalidateMeasure(); } // // NOTE: // // If the collection is NOT in view mode, RowPresenter should be mentor of the Collection. // But if presenter + collection are used to restyle ListBoxItems and the ItemsPanel is // VSP, there are 2 problems: // // 1. each RowPresenter want to be the mentor, too many context change event // 2. when doing scroll, VSP will dispose those LB items which are out of view. But they // are still referenced by the Collecion (at the Owner property) - memory leak. // // Solution: // If RowPresenter is inside an ItemsControl (IC\LB\CB), use the ItemsControl as the // mentor. Therefore, // - context change is minimized because ItemsControl for different items is the same; // - no memory leak because when viturlizing, only dispose items not the IC itself. // private FrameworkElement GetStableAncester() { ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(TemplatedParent); return (ic != null) ? ic : (FrameworkElement)this; } // if and only if both conditions below are satisfied, row presenter visual is ready. // 1. is initialized, which ensures RowPresenter is created // 2. !NeedUpdateVisualTree, which ensures all visual elements generated by RowPresenter are created private bool IsPresenterVisualReady { get { return (IsInitialized && !NeedUpdateVisualTree); } } ////// Handle events from the centralized event table /// bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs args) { if (managerType == typeof(InternalCollectionChangedEventManager)) { ColumnCollectionChanged(sender, (NotifyCollectionChangedEventArgs)args); } else { return false; // unrecognized event } return true; } ////// Handler of GridViewColumnCollection.CollectionChanged event. /// private void ColumnCollectionChanged(object sender, NotifyCollectionChangedEventArgs arg) { GridViewColumnCollectionChangedEventArgs e = arg as GridViewColumnCollectionChangedEventArgs; if (e != null && IsPresenterVisualReady)// if and only if rowpresenter's visual is ready, shall rowpresenter go ahead process the event. { // Property of one column changed if (e.Column != null) { OnColumnPropertyChanged(e.Column, e.PropertyName); } else { OnColumnCollectionChanged(e); } } } private UIElementCollection _uiElementCollection; private bool _needUpdateVisualTree = true; private List_desiredWidthList; #endregion } /// /// Manager for the GridViewColumnCollection.CollectionChanged event. /// internal class InternalCollectionChangedEventManager : WeakEventManager { #region Constructors // // Constructors // private InternalCollectionChangedEventManager() { } #endregion Constructors #region Public Methods // // Public Methods // ////// Add a listener to the given source's event. /// public static void AddListener(GridViewColumnCollection source, IWeakEventListener listener) { if (source == null) throw new ArgumentNullException("source"); if (listener == null) throw new ArgumentNullException("listener"); CurrentManager.ProtectedAddListener(source, listener); } ////// Remove a listener to the given source's event. /// public static void RemoveListener(GridViewColumnCollection source, IWeakEventListener listener) { if (source == null) throw new ArgumentNullException("source"); if (listener == null) throw new ArgumentNullException("listener"); CurrentManager.ProtectedRemoveListener(source, listener); } #endregion Public Methods #region Protected Methods // // Protected Methods // ////// Listen to the given source for the event. /// protected override void StartListening(object source) { GridViewColumnCollection typedSource = (GridViewColumnCollection)source; typedSource.InternalCollectionChanged += new NotifyCollectionChangedEventHandler(OnCollectionChanged); } ////// Stop listening to the given source for the event. /// protected override void StopListening(object source) { GridViewColumnCollection typedSource = (GridViewColumnCollection)source; typedSource.InternalCollectionChanged -= new NotifyCollectionChangedEventHandler(OnCollectionChanged); } #endregion Protected Methods #region Private Properties // // Private Properties // // get the event manager for the current thread private static InternalCollectionChangedEventManager CurrentManager { get { Type managerType = typeof(InternalCollectionChangedEventManager); InternalCollectionChangedEventManager manager = (InternalCollectionChangedEventManager)GetCurrentManager(managerType); // at first use, create and register a new manager if (manager == null) { manager = new InternalCollectionChangedEventManager(); SetCurrentManager(managerType, manager); } return manager; } } #endregion Private Properties #region Private Methods // // Private Methods // // event handler for CollectionChanged event private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { DeliverEvent(sender, args); } #endregion Private Methods } } // 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
- Resources.Designer.cs
- QuadraticBezierSegment.cs
- TrustManager.cs
- XmlWrappingReader.cs
- RegionData.cs
- System.Data.OracleClient_BID.cs
- ThreadExceptionDialog.cs
- ConfigXmlElement.cs
- DropDownButton.cs
- BindingGroup.cs
- ConfigXmlCDataSection.cs
- NavigatingCancelEventArgs.cs
- Row.cs
- Base64Decoder.cs
- ParentUndoUnit.cs
- PackageDigitalSignatureManager.cs
- WorkflowServiceNamespace.cs
- ZoomPercentageConverter.cs
- SystemException.cs
- OrthographicCamera.cs
- NavigationPropertyEmitter.cs
- RSAOAEPKeyExchangeFormatter.cs
- GenericAuthenticationEventArgs.cs
- TraceData.cs
- DocumentationServerProtocol.cs
- HttpChannelHelper.cs
- TextEndOfParagraph.cs
- PackageProperties.cs
- RequiredFieldValidator.cs
- ProcessHostServerConfig.cs
- CompensationTokenData.cs
- DrawListViewItemEventArgs.cs
- Int16Animation.cs
- PolyLineSegmentFigureLogic.cs
- DbException.cs
- OracleCommandBuilder.cs
- TableCellCollection.cs
- DataBindingHandlerAttribute.cs
- QueryOutputWriter.cs
- MobileTemplatedControlDesigner.cs
- FixedDocument.cs
- CheckBox.cs
- BinaryObjectInfo.cs
- NegationPusher.cs
- CheckBoxAutomationPeer.cs
- DataGridViewSelectedColumnCollection.cs
- RichTextBoxConstants.cs
- ErrorLog.cs
- RealizationContext.cs
- IgnoreDeviceFilterElement.cs
- SystemException.cs
- ClientCultureInfo.cs
- SystemFonts.cs
- path.cs
- DocumentXmlWriter.cs
- InternalUserCancelledException.cs
- HTTPNotFoundHandler.cs
- NativeMethods.cs
- TextTreeTextBlock.cs
- Mapping.cs
- MatrixTransform.cs
- EntityException.cs
- CursorConverter.cs
- PublisherMembershipCondition.cs
- Span.cs
- SafePEFileHandle.cs
- GregorianCalendar.cs
- WebConfigurationHostFileChange.cs
- NotifyCollectionChangedEventArgs.cs
- NameValuePair.cs
- PriorityQueue.cs
- AuthenticationModuleElementCollection.cs
- PersonalizationStateInfo.cs
- DataViewSetting.cs
- XsdDateTime.cs
- AuthenticateEventArgs.cs
- DataGridState.cs
- ArgumentOutOfRangeException.cs
- Expressions.cs
- EllipseGeometry.cs
- InvalidOperationException.cs
- ContextMenu.cs
- SplitterEvent.cs
- unsafeIndexingFilterStream.cs
- ToolStripDropDownClosedEventArgs.cs
- RowToFieldTransformer.cs
- NativeMethods.cs
- _TimerThread.cs
- DataControlField.cs
- NavigationHelper.cs
- UICuesEvent.cs
- ClusterUtils.cs
- RuntimeArgumentHandle.cs
- XamlStyleSerializer.cs
- CodeAssignStatement.cs
- BufferedWebEventProvider.cs
- MarshalByRefObject.cs
- PolicyException.cs
- XmlEntity.cs
- ExtenderProvidedPropertyAttribute.cs