Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / ReverseInheritProperty.cs / 1305600 / ReverseInheritProperty.cs
using System; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Media; using System.Windows.Input; using MS.Internal; namespace System.Windows { internal abstract class ReverseInheritProperty { internal ReverseInheritProperty( DependencyPropertyKey flagKey, CoreFlags flagCache, CoreFlags flagChanged) : this(flagKey, flagCache, flagChanged, CoreFlags.None, CoreFlags.None) { } internal ReverseInheritProperty( DependencyPropertyKey flagKey, CoreFlags flagCache, CoreFlags flagChanged, CoreFlags flagOldOriginCache, CoreFlags flagNewOriginCache) { FlagKey = flagKey; FlagCache = flagCache; FlagChanged = flagChanged; FlagOldOriginCache = flagOldOriginCache; FlagNewOriginCache = flagNewOriginCache; } internal abstract void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue); internal void OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, ref DeferredElementTreeState oldTreeState) { OnOriginValueChanged(oldOrigin, newOrigin, null, ref oldTreeState, null); } internal void OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, IListotherOrigins, ref DeferredElementTreeState oldTreeState, Action originChangedAction) { DeferredElementTreeState treeStateLocalCopy = oldTreeState; oldTreeState = null; // Determine if one needs to raise notifications of elements // affected by the origin change irrespective of other origins bool setOriginCacheFlag = ((originChangedAction != null) && (FlagOldOriginCache != CoreFlags.None) && (FlagNewOriginCache != CoreFlags.None)); // Step #1 // Update the cache flags for all elements in the ancestry // of the element that got turned off and record the changed nodes if (oldOrigin != null) { SetCacheFlagInAncestry(oldOrigin, false, treeStateLocalCopy, true, setOriginCacheFlag); } // Step #2 // Update the cache flags for all elements in the ancestry // of the element that got turned on and record the changed nodes if (newOrigin != null) { SetCacheFlagInAncestry(newOrigin, true, null, true, setOriginCacheFlag); } int otherCount = (otherOrigins != null) ? otherOrigins.Count : 0; for (int i = 0; i < otherCount; i++) { // setOriginCacheFlag is false, because these flags should not be affected by other origins SetCacheFlagInAncestry(otherOrigins[i], true, null, false, /*setOriginCacheFlag*/ false); } // Step #3 // Fire value changed on elements in the ancestry of the element that got turned off. if (oldOrigin != null) { FirePropertyChangeInAncestry(oldOrigin, true /* oldValue */, treeStateLocalCopy, originChangedAction); } // Step #4 // Fire value changed on elements in the ancestry of the element that got turned on. if (newOrigin != null) { FirePropertyChangeInAncestry(newOrigin, false /* oldValue */, null, originChangedAction); } if (oldTreeState == null && treeStateLocalCopy != null) { // Now that we have applied the old tree state, throw it away. treeStateLocalCopy.Clear(); oldTreeState = treeStateLocalCopy; } } private void SetCacheFlagInAncestry(DependencyObject element, bool newValue, DeferredElementTreeState treeState, bool shortCircuit, bool setOriginCacheFlag) { UIElement uie; ContentElement ce; UIElement3D uie3D; CastElement(element, out uie, out ce, out uie3D); bool isFlagSet = IsFlagSet(uie, ce, uie3D, FlagCache); bool isFla----ginCacheSet = (setOriginCacheFlag ? IsFlagSet(uie, ce, uie3D, (newValue ? FlagNewOriginCache : FlagOldOriginCache)) : false); // If the cache flag value is undergoing change, record it and // propagate the change to the ancestors. if ((newValue != isFlagSet) || (setOriginCacheFlag && !isFla----ginCacheSet) || !shortCircuit) { if (newValue != isFlagSet) { SetFlag(uie, ce, uie3D, FlagCache, newValue); // NOTE: we toggle the changed flag instead of setting it so that that way common // ancestors show resultant unchanged and do not receive any change notification. SetFlag(uie, ce, uie3D, FlagChanged, !IsFlagSet(uie, ce, uie3D, FlagChanged)); } if (setOriginCacheFlag && !isFla----ginCacheSet) { SetFlag(uie, ce, uie3D, (newValue ? FlagNewOriginCache : FlagOldOriginCache), true); } // Check for block reverse inheritance flag, elements like popup want to set this. if (BlockReverseInheritance(uie, ce, uie3D)) { return; } // Propagate the flag up the visual and logical trees. Note our // minimal optimization check to avoid walking both the core // and logical parents if they are the same. { DependencyObject coreParent = DeferredElementTreeState.GetInputElementParent(element, treeState); DependencyObject logicalParent = DeferredElementTreeState.GetLogicalParent(element, treeState); if (coreParent != null) { SetCacheFlagInAncestry(coreParent, newValue, treeState, shortCircuit, setOriginCacheFlag); } if (logicalParent != null && logicalParent != coreParent) { SetCacheFlagInAncestry(logicalParent, newValue, treeState, shortCircuit, setOriginCacheFlag); } } } } private void FirePropertyChangeInAncestry(DependencyObject element, bool oldValue, DeferredElementTreeState treeState, Action originChangedAction) { UIElement uie; ContentElement ce; UIElement3D uie3D; CastElement(element, out uie, out ce, out uie3D); bool flagChanged = IsFlagSet(uie, ce, uie3D, FlagChanged); bool isFlagOldOriginCacheSet = ((FlagOldOriginCache == CoreFlags.None) ? false : IsFlagSet(uie, ce, uie3D, FlagOldOriginCache)); bool isFlagNewOriginCacheSet = ((FlagNewOriginCache == CoreFlags.None) ? false : IsFlagSet(uie, ce, uie3D, FlagNewOriginCache)); if (flagChanged || isFlagOldOriginCacheSet || isFlagNewOriginCacheSet) { if (flagChanged) { // if FlagChanged bit is set, then the value has changed effectively // after considering all the origins. Hence change the property value // and fire notifications. SetFlag(uie, ce, uie3D, FlagChanged, false); if (oldValue) { element.ClearValue(FlagKey); } else { element.SetValue(FlagKey, true); } FireNotifications(uie, ce, uie3D, oldValue); } if (isFlagOldOriginCacheSet || isFlagNewOriginCacheSet) { SetFlag(uie, ce, uie3D, FlagOldOriginCache, false); SetFlag(uie, ce, uie3D, FlagNewOriginCache, false); if (isFlagOldOriginCacheSet != isFlagNewOriginCacheSet) { // if either FlagOldOriginCache or FlagNewOriginCache // are set, then the origin change has affected this node // and hence originChangedAction should be executed. Debug.Assert(originChangedAction != null); originChangedAction(element, oldValue); } } // Check for block reverse inheritance flag, elements like popup want to set this. if (BlockReverseInheritance(uie, ce, uie3D)) { return; } // Call FirePropertyChange up the visual and logical trees. // Note our minimal optimization check to avoid walking both // the core and logical parents if they are the same. { DependencyObject coreParent = DeferredElementTreeState.GetInputElementParent(element, treeState); DependencyObject logicalParent = DeferredElementTreeState.GetLogicalParent(element, treeState); if (coreParent != null) { FirePropertyChangeInAncestry(coreParent, oldValue, treeState, originChangedAction); } if (logicalParent != null && logicalParent != coreParent) { FirePropertyChangeInAncestry(logicalParent, oldValue, treeState, originChangedAction); } } } } ///////////////////////////////////////////////////////////////////// private static bool BlockReverseInheritance(UIElement uie, ContentElement ce, UIElement3D uie3D) { if (uie != null) { return uie.BlockReverseInheritance(); } else if (ce != null) { return ce.BlockReverseInheritance(); } else if (uie3D != null) { return uie3D.BlockReverseInheritance(); } return false; } ///////////////////////////////////////////////////////////////////// private static void SetFlag(UIElement uie, ContentElement ce, UIElement3D uie3D, CoreFlags flag, bool value) { if (uie != null) { uie.WriteFlag(flag, value); } else if (ce != null) { ce.WriteFlag(flag, value); } else if (uie3D != null) { uie3D.WriteFlag(flag, value); } } ///////////////////////////////////////////////////////////////////// private static bool IsFlagSet(UIElement uie, ContentElement ce, UIElement3D uie3D, CoreFlags flag) { if (uie != null) { return uie.ReadFlag(flag); } else if (ce != null) { return ce.ReadFlag(flag); } else if (uie3D != null) { return uie3D.ReadFlag(flag); } return false; } ///////////////////////////////////////////////////////////////////// private static void CastElement(DependencyObject o, out UIElement uie, out ContentElement ce, out UIElement3D uie3D) { uie = o as UIElement; ce = (uie != null) ? null : o as ContentElement; uie3D = (uie != null || ce != null) ? null : o as UIElement3D; } ///////////////////////////////////////////////////////////////////// protected DependencyPropertyKey FlagKey; protected CoreFlags FlagCache; protected CoreFlags FlagChanged; protected CoreFlags FlagOldOriginCache; // Flag to keep track of elements in the path of old origin protected CoreFlags FlagNewOriginCache; // Flag to keep track of elements in the path of new origin } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Media; using System.Windows.Input; using MS.Internal; namespace System.Windows { internal abstract class ReverseInheritProperty { internal ReverseInheritProperty( DependencyPropertyKey flagKey, CoreFlags flagCache, CoreFlags flagChanged) : this(flagKey, flagCache, flagChanged, CoreFlags.None, CoreFlags.None) { } internal ReverseInheritProperty( DependencyPropertyKey flagKey, CoreFlags flagCache, CoreFlags flagChanged, CoreFlags flagOldOriginCache, CoreFlags flagNewOriginCache) { FlagKey = flagKey; FlagCache = flagCache; FlagChanged = flagChanged; FlagOldOriginCache = flagOldOriginCache; FlagNewOriginCache = flagNewOriginCache; } internal abstract void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue); internal void OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, ref DeferredElementTreeState oldTreeState) { OnOriginValueChanged(oldOrigin, newOrigin, null, ref oldTreeState, null); } internal void OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, IList otherOrigins, ref DeferredElementTreeState oldTreeState, Action originChangedAction) { DeferredElementTreeState treeStateLocalCopy = oldTreeState; oldTreeState = null; // Determine if one needs to raise notifications of elements // affected by the origin change irrespective of other origins bool setOriginCacheFlag = ((originChangedAction != null) && (FlagOldOriginCache != CoreFlags.None) && (FlagNewOriginCache != CoreFlags.None)); // Step #1 // Update the cache flags for all elements in the ancestry // of the element that got turned off and record the changed nodes if (oldOrigin != null) { SetCacheFlagInAncestry(oldOrigin, false, treeStateLocalCopy, true, setOriginCacheFlag); } // Step #2 // Update the cache flags for all elements in the ancestry // of the element that got turned on and record the changed nodes if (newOrigin != null) { SetCacheFlagInAncestry(newOrigin, true, null, true, setOriginCacheFlag); } int otherCount = (otherOrigins != null) ? otherOrigins.Count : 0; for (int i = 0; i < otherCount; i++) { // setOriginCacheFlag is false, because these flags should not be affected by other origins SetCacheFlagInAncestry(otherOrigins[i], true, null, false, /*setOriginCacheFlag*/ false); } // Step #3 // Fire value changed on elements in the ancestry of the element that got turned off. if (oldOrigin != null) { FirePropertyChangeInAncestry(oldOrigin, true /* oldValue */, treeStateLocalCopy, originChangedAction); } // Step #4 // Fire value changed on elements in the ancestry of the element that got turned on. if (newOrigin != null) { FirePropertyChangeInAncestry(newOrigin, false /* oldValue */, null, originChangedAction); } if (oldTreeState == null && treeStateLocalCopy != null) { // Now that we have applied the old tree state, throw it away. treeStateLocalCopy.Clear(); oldTreeState = treeStateLocalCopy; } } private void SetCacheFlagInAncestry(DependencyObject element, bool newValue, DeferredElementTreeState treeState, bool shortCircuit, bool setOriginCacheFlag) { UIElement uie; ContentElement ce; UIElement3D uie3D; CastElement(element, out uie, out ce, out uie3D); bool isFlagSet = IsFlagSet(uie, ce, uie3D, FlagCache); bool isFla----ginCacheSet = (setOriginCacheFlag ? IsFlagSet(uie, ce, uie3D, (newValue ? FlagNewOriginCache : FlagOldOriginCache)) : false); // If the cache flag value is undergoing change, record it and // propagate the change to the ancestors. if ((newValue != isFlagSet) || (setOriginCacheFlag && !isFla----ginCacheSet) || !shortCircuit) { if (newValue != isFlagSet) { SetFlag(uie, ce, uie3D, FlagCache, newValue); // NOTE: we toggle the changed flag instead of setting it so that that way common // ancestors show resultant unchanged and do not receive any change notification. SetFlag(uie, ce, uie3D, FlagChanged, !IsFlagSet(uie, ce, uie3D, FlagChanged)); } if (setOriginCacheFlag && !isFla----ginCacheSet) { SetFlag(uie, ce, uie3D, (newValue ? FlagNewOriginCache : FlagOldOriginCache), true); } // Check for block reverse inheritance flag, elements like popup want to set this. if (BlockReverseInheritance(uie, ce, uie3D)) { return; } // Propagate the flag up the visual and logical trees. Note our // minimal optimization check to avoid walking both the core // and logical parents if they are the same. { DependencyObject coreParent = DeferredElementTreeState.GetInputElementParent(element, treeState); DependencyObject logicalParent = DeferredElementTreeState.GetLogicalParent(element, treeState); if (coreParent != null) { SetCacheFlagInAncestry(coreParent, newValue, treeState, shortCircuit, setOriginCacheFlag); } if (logicalParent != null && logicalParent != coreParent) { SetCacheFlagInAncestry(logicalParent, newValue, treeState, shortCircuit, setOriginCacheFlag); } } } } private void FirePropertyChangeInAncestry(DependencyObject element, bool oldValue, DeferredElementTreeState treeState, Action originChangedAction) { UIElement uie; ContentElement ce; UIElement3D uie3D; CastElement(element, out uie, out ce, out uie3D); bool flagChanged = IsFlagSet(uie, ce, uie3D, FlagChanged); bool isFlagOldOriginCacheSet = ((FlagOldOriginCache == CoreFlags.None) ? false : IsFlagSet(uie, ce, uie3D, FlagOldOriginCache)); bool isFlagNewOriginCacheSet = ((FlagNewOriginCache == CoreFlags.None) ? false : IsFlagSet(uie, ce, uie3D, FlagNewOriginCache)); if (flagChanged || isFlagOldOriginCacheSet || isFlagNewOriginCacheSet) { if (flagChanged) { // if FlagChanged bit is set, then the value has changed effectively // after considering all the origins. Hence change the property value // and fire notifications. SetFlag(uie, ce, uie3D, FlagChanged, false); if (oldValue) { element.ClearValue(FlagKey); } else { element.SetValue(FlagKey, true); } FireNotifications(uie, ce, uie3D, oldValue); } if (isFlagOldOriginCacheSet || isFlagNewOriginCacheSet) { SetFlag(uie, ce, uie3D, FlagOldOriginCache, false); SetFlag(uie, ce, uie3D, FlagNewOriginCache, false); if (isFlagOldOriginCacheSet != isFlagNewOriginCacheSet) { // if either FlagOldOriginCache or FlagNewOriginCache // are set, then the origin change has affected this node // and hence originChangedAction should be executed. Debug.Assert(originChangedAction != null); originChangedAction(element, oldValue); } } // Check for block reverse inheritance flag, elements like popup want to set this. if (BlockReverseInheritance(uie, ce, uie3D)) { return; } // Call FirePropertyChange up the visual and logical trees. // Note our minimal optimization check to avoid walking both // the core and logical parents if they are the same. { DependencyObject coreParent = DeferredElementTreeState.GetInputElementParent(element, treeState); DependencyObject logicalParent = DeferredElementTreeState.GetLogicalParent(element, treeState); if (coreParent != null) { FirePropertyChangeInAncestry(coreParent, oldValue, treeState, originChangedAction); } if (logicalParent != null && logicalParent != coreParent) { FirePropertyChangeInAncestry(logicalParent, oldValue, treeState, originChangedAction); } } } } ///////////////////////////////////////////////////////////////////// private static bool BlockReverseInheritance(UIElement uie, ContentElement ce, UIElement3D uie3D) { if (uie != null) { return uie.BlockReverseInheritance(); } else if (ce != null) { return ce.BlockReverseInheritance(); } else if (uie3D != null) { return uie3D.BlockReverseInheritance(); } return false; } ///////////////////////////////////////////////////////////////////// private static void SetFlag(UIElement uie, ContentElement ce, UIElement3D uie3D, CoreFlags flag, bool value) { if (uie != null) { uie.WriteFlag(flag, value); } else if (ce != null) { ce.WriteFlag(flag, value); } else if (uie3D != null) { uie3D.WriteFlag(flag, value); } } ///////////////////////////////////////////////////////////////////// private static bool IsFlagSet(UIElement uie, ContentElement ce, UIElement3D uie3D, CoreFlags flag) { if (uie != null) { return uie.ReadFlag(flag); } else if (ce != null) { return ce.ReadFlag(flag); } else if (uie3D != null) { return uie3D.ReadFlag(flag); } return false; } ///////////////////////////////////////////////////////////////////// private static void CastElement(DependencyObject o, out UIElement uie, out ContentElement ce, out UIElement3D uie3D) { uie = o as UIElement; ce = (uie != null) ? null : o as ContentElement; uie3D = (uie != null || ce != null) ? null : o as UIElement3D; } ///////////////////////////////////////////////////////////////////// protected DependencyPropertyKey FlagKey; protected CoreFlags FlagCache; protected CoreFlags FlagChanged; protected CoreFlags FlagOldOriginCache; // Flag to keep track of elements in the path of old origin protected CoreFlags FlagNewOriginCache; // Flag to keep track of elements in the path of new origin } } // 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
- SqlDataSourceCommandEventArgs.cs
- WindowsFormsSynchronizationContext.cs
- AnnotationStore.cs
- SuspendDesigner.cs
- RenderData.cs
- WebPartZoneCollection.cs
- RenderingBiasValidation.cs
- HttpModuleAction.cs
- AnyReturnReader.cs
- TreeViewEvent.cs
- ListViewDeleteEventArgs.cs
- XmlSequenceWriter.cs
- GridSplitterAutomationPeer.cs
- DetailsViewPagerRow.cs
- _Connection.cs
- Errors.cs
- PropertyValueUIItem.cs
- ObjectDataSourceStatusEventArgs.cs
- ToolboxDataAttribute.cs
- InternalDuplexChannelListener.cs
- CommonRemoteMemoryBlock.cs
- JsonUriDataContract.cs
- Configuration.cs
- ReadOnlyAttribute.cs
- SymLanguageVendor.cs
- ToolStripItemTextRenderEventArgs.cs
- DataGridRow.cs
- DataGridViewTopLeftHeaderCell.cs
- FileDialog.cs
- EmptyCollection.cs
- ContentElement.cs
- ConfigurationManager.cs
- DictionaryEntry.cs
- DataGridTableCollection.cs
- WeakEventManager.cs
- Serializer.cs
- CqlGenerator.cs
- HttpModuleAction.cs
- DefaultPropertyAttribute.cs
- RayHitTestParameters.cs
- Label.cs
- ItemCheckedEvent.cs
- SqlRetyper.cs
- DataControlFieldHeaderCell.cs
- AnimationException.cs
- OleDbPermission.cs
- InputEventArgs.cs
- _LoggingObject.cs
- HMACSHA1.cs
- TextServicesProperty.cs
- WrappedKeySecurityTokenParameters.cs
- BitSet.cs
- AnnotationObservableCollection.cs
- Crc32Helper.cs
- ConfigXmlText.cs
- Convert.cs
- TemplateColumn.cs
- GeneralTransform2DTo3D.cs
- DriveInfo.cs
- ToolBar.cs
- Rotation3D.cs
- SqlProcedureAttribute.cs
- RecordBuilder.cs
- DrawingVisual.cs
- EntityStoreSchemaFilterEntry.cs
- TargetInvocationException.cs
- XmlAttributeAttribute.cs
- DuplicateWaitObjectException.cs
- FixedSOMTextRun.cs
- _TransmitFileOverlappedAsyncResult.cs
- IHttpResponseInternal.cs
- CustomPopupPlacement.cs
- SystemSounds.cs
- DelayedRegex.cs
- DescendentsWalkerBase.cs
- HtmlTableCellCollection.cs
- DeflateInput.cs
- CustomLineCap.cs
- IntellisenseTextBox.cs
- XmlSerializer.cs
- ObjectTypeMapping.cs
- DbProviderServices.cs
- SubordinateTransaction.cs
- SafeProcessHandle.cs
- SerialPort.cs
- ObfuscateAssemblyAttribute.cs
- SaveFileDialog.cs
- Error.cs
- ReferentialConstraint.cs
- TypeConvertions.cs
- TreeNodeMouseHoverEvent.cs
- EndpointDiscoveryMetadataCD1.cs
- TextDocumentView.cs
- HttpRequest.cs
- BaseDataBoundControl.cs
- EventArgs.cs
- ObjectContext.cs
- ExtractedStateEntry.cs
- PointCollectionConverter.cs
- SchemaLookupTable.cs