Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / System / Windows / EffectiveValueEntry.cs / 1305600 / EffectiveValueEntry.cs
/****************************************************************************\ * * File: EffectiveValueEntry.cs * * This file describes an entry in the EffectiveValues list held by a * DependencyObject. * * Copyright (C) 2005 by Microsoft Corporation. All rights reserved. * \***************************************************************************/ using MS.Internal.WindowsBase; // FriendAccessAllowed using System.Collections; // IDictionary using System.Diagnostics; // Debug.Assert namespace System.Windows { [FriendAccessAllowed] // Built into Base, also used by Core & Framework. internal struct EffectiveValueEntry { #region InternalMethods internal static EffectiveValueEntry CreateDefaultValueEntry(DependencyProperty dp, object value) { EffectiveValueEntry entry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Default); entry.Value = value; return entry; } internal EffectiveValueEntry(DependencyProperty dp) { _propertyIndex = (short) dp.GlobalIndex; _value = null; _source = (FullValueSource) BaseValueSourceInternal.Unknown; } internal EffectiveValueEntry(DependencyProperty dp, BaseValueSourceInternal valueSource) { _propertyIndex = (short) dp.GlobalIndex; _value = DependencyProperty.UnsetValue; _source = (FullValueSource) valueSource; } internal EffectiveValueEntry(DependencyProperty dp, FullValueSource fullValueSource) { _propertyIndex = (short) dp.GlobalIndex; _value = DependencyProperty.UnsetValue; _source = fullValueSource; } internal void SetExpressionValue(object value, object baseValue) { Debug.Assert(value != DependencyProperty.UnsetValue); ModifiedValue modifiedValue = EnsureModifiedValue(); modifiedValue.ExpressionValue = value; IsExpression = true; IsDeferredReference = value is DeferredReference; Debug.Assert(Object.Equals(modifiedValue.BaseValue, baseValue)); Debug.Assert(!(baseValue is DeferredReference)); Debug.Assert(IsDeferredReference == (value is DeferredReference)); } internal void SetAnimatedValue(object value, object baseValue) { Debug.Assert((value != DependencyProperty.UnsetValue) && !(value is DeferredReference)); ModifiedValue modifiedValue = EnsureModifiedValue(); modifiedValue.AnimatedValue = value; IsAnimated = true; // Animated values should never be deferred IsDeferredReference = false; Debug.Assert(!(modifiedValue.AnimatedValue is DeferredReference)); Debug.Assert(Object.Equals(modifiedValue.BaseValue, baseValue) || Object.Equals(modifiedValue.ExpressionValue, baseValue)); Debug.Assert(!(baseValue is DeferredReference) && ! (modifiedValue.BaseValue is DeferredReference) && ! (modifiedValue.ExpressionValue is DeferredReference)); } internal void SetCoercedValue(object value, object baseValue, bool skipBaseValueChecks, bool coerceWithCurrentValue) { Debug.Assert(value != DependencyProperty.UnsetValue && !((value is DeferredReference) && !coerceWithCurrentValue)); // if this is already a CoercedWithControlValue entry, we are applying a // second coercion (e.g. from the CoerceValueCallback). The baseValue // passed in is the result of the control-value coercion, but for the // purposes of this method we should use the original base value instead. if (IsCoercedWithCurrentValue) { baseValue = ModifiedValue.BaseValue; } ModifiedValue modifiedValue = EnsureModifiedValue(); modifiedValue.CoercedValue = value; IsCoerced = true; IsCoercedWithCurrentValue = coerceWithCurrentValue; // The only CoercedValues that can be deferred are Control values. if (coerceWithCurrentValue) { IsDeferredReference = (value is DeferredReference); } else { IsDeferredReference = false; } Debug.Assert(skipBaseValueChecks || Object.Equals(modifiedValue.BaseValue, baseValue) || Object.Equals(modifiedValue.ExpressionValue, baseValue) || Object.Equals(modifiedValue.AnimatedValue, baseValue)); Debug.Assert(!(baseValue is DeferredReference) && ! (modifiedValue.BaseValue is DeferredReference) && ! (modifiedValue.ExpressionValue is DeferredReference) && ! (modifiedValue.AnimatedValue is DeferredReference)); } internal void ResetAnimatedValue() { if (IsAnimated) { ModifiedValue modifiedValue = ModifiedValue; modifiedValue.AnimatedValue = null; IsAnimated = false; if (!HasModifiers) { Value = modifiedValue.BaseValue; } else { // The setter takes care of the IsDeferred flag no need to compute it twice. ComputeIsDeferred(); } } } internal void ResetCoercedValue() { if (IsCoerced) { ModifiedValue modifiedValue = ModifiedValue; modifiedValue.CoercedValue = null; IsCoerced = false; if (!HasModifiers) { Value = modifiedValue.BaseValue; } else { ComputeIsDeferred(); } } } // remove all modifiers, retain value source, and set value to supplied value internal void ResetValue(object value, bool hasExpressionMarker) { _source &= FullValueSource.ValueSourceMask; _value = value; if (hasExpressionMarker) { HasExpressionMarker = true; } else { ComputeIsDeferred(); } Debug.Assert(hasExpressionMarker == (value == DependencyObject.ExpressionInAlternativeStore), "hasExpressionMarker flag must match value"); } // add an expression marker back as the base value for an expression value internal void RestoreExpressionMarker() { if (HasModifiers) { ModifiedValue entry = ModifiedValue; entry.ExpressionValue = entry.BaseValue; entry.BaseValue = DependencyObject.ExpressionInAlternativeStore; _source |= FullValueSource.IsExpression | FullValueSource.HasExpressionMarker; //recompute the isDeferredReference flag as it may have changed ComputeIsDeferred(); } else { object value = Value; Value = DependencyObject.ExpressionInAlternativeStore; SetExpressionValue(value, DependencyObject.ExpressionInAlternativeStore); _source |= FullValueSource.HasExpressionMarker; } } // Computes and set the IsDeferred hint flag. // This take into account all flags and should only be used sparingly. private void ComputeIsDeferred() { bool isDeferredReference = false; if (!HasModifiers) { isDeferredReference = Value is DeferredReference; } else if (ModifiedValue != null) { if (IsCoercedWithCurrentValue) { isDeferredReference = ModifiedValue.CoercedValue is DeferredReference; } else if (IsExpression) { isDeferredReference = ModifiedValue.ExpressionValue is DeferredReference; } // For animated values isDeferred will always be false. } IsDeferredReference = isDeferredReference; } #endregion InternalMethods #region InternalProperties public int PropertyIndex { get { return _propertyIndex; } set { _propertyIndex = (short)value; } } ////// If HasModifiers is true then it holds the value /// else it holds the modified value instance /// internal object Value { get { return _value; } set { _value = value; IsDeferredReference = value is DeferredReference; Debug.Assert(value is DeferredReference == IsDeferredReference); } } internal BaseValueSourceInternal BaseValueSourceInternal { get { return (BaseValueSourceInternal)(_source & FullValueSource.ValueSourceMask); } set { _source = (_source & ~FullValueSource.ValueSourceMask) | (FullValueSource)value; } } internal bool IsDeferredReference { get { // When this flag is true we treat it as a hint rather than a guarantee and update // it if is out of [....]. When the flag is false, however we expect it to guarantee // that the value isn't a DeferredReference. bool isDeferredReference = ReadPrivateFlag(FullValueSource.IsPotentiallyADeferredReference); if (isDeferredReference) { // Check if the value is really a deferred reference ComputeIsDeferred(); isDeferredReference = ReadPrivateFlag(FullValueSource.IsPotentiallyADeferredReference); } return isDeferredReference; } private set { WritePrivateFlag(FullValueSource.IsPotentiallyADeferredReference, value); } } internal bool IsExpression { get { return ReadPrivateFlag(FullValueSource.IsExpression); } private set { WritePrivateFlag(FullValueSource.IsExpression, value); } } internal bool IsAnimated { get { return ReadPrivateFlag(FullValueSource.IsAnimated); } private set { WritePrivateFlag(FullValueSource.IsAnimated, value); } } internal bool IsCoerced { get { return ReadPrivateFlag(FullValueSource.IsCoerced); } private set { WritePrivateFlag(FullValueSource.IsCoerced, value); } } internal bool HasModifiers { get { return (_source & FullValueSource.ModifiersMask) != 0; } } internal FullValueSource FullValueSource { get { return _source; } } internal bool HasExpressionMarker { get { return ReadPrivateFlag(FullValueSource.HasExpressionMarker); } set { WritePrivateFlag(FullValueSource.HasExpressionMarker, value); } } internal bool IsCoercedWithCurrentValue { get { return ReadPrivateFlag(FullValueSource.IsCoercedWithCurrentValue); } set { WritePrivateFlag(FullValueSource.IsCoercedWithCurrentValue, value); } } internal EffectiveValueEntry GetFlattenedEntry(RequestFlags requests) { if ((_source & (FullValueSource.ModifiersMask | FullValueSource.HasExpressionMarker)) == 0) { // If the property does not have any modifiers // then just return the base value. return this; } if (!HasModifiers) { Debug.Assert(HasExpressionMarker); // This is the case when some one stuck an expression into // an alternate store such as a style or a template but the // new value for the expression has not been evaluated yet. // In the intermediate we need to return the default value // for the property. This problem was manifested in DRTDocumentViewer. EffectiveValueEntry unsetEntry = new EffectiveValueEntry(); unsetEntry.BaseValueSourceInternal = BaseValueSourceInternal; unsetEntry.PropertyIndex = PropertyIndex; return unsetEntry; } // else entry has modifiers EffectiveValueEntry entry = new EffectiveValueEntry(); entry.BaseValueSourceInternal = BaseValueSourceInternal; entry.PropertyIndex = PropertyIndex; entry.IsDeferredReference = IsDeferredReference; // If the property has a modifier return the modified value Debug.Assert(ModifiedValue != null); // outside of DO, we flatten modified value ModifiedValue modifiedValue = ModifiedValue; // Note that the modified values have an order of precedence // 1. Coerced Value (including Current value) // 2. Animated Value // 3. Expression Value // Also note that we support any arbitrary combinations of these // modifiers and will yet the precedence metioned above. if (IsCoerced) { if ((requests & RequestFlags.CoercionBaseValue) == 0) { entry.Value = modifiedValue.CoercedValue; } else { // This is the case when CoerceValue tries to query // the old base value for the property if (IsCoercedWithCurrentValue) { entry.Value = modifiedValue.CoercedValue; } else if (IsAnimated && ((requests & RequestFlags.AnimationBaseValue) == 0)) { entry.Value = modifiedValue.AnimatedValue; } else if (IsExpression) { entry.Value = modifiedValue.ExpressionValue; } else { entry.Value = modifiedValue.BaseValue; } } } else if (IsAnimated) { if ((requests & RequestFlags.AnimationBaseValue) == 0) { entry.Value = modifiedValue.AnimatedValue; } else { // This is the case when [UI/Content]Element are // requesting the base value of an animation. if (IsExpression) { entry.Value = modifiedValue.ExpressionValue; } else { entry.Value = modifiedValue.BaseValue; } } } else { Debug.Assert(IsExpression == true); object expressionValue = modifiedValue.ExpressionValue; entry.Value = expressionValue; } Debug.Assert(entry.IsDeferredReference == (entry.Value is DeferredReference), "Value and DeferredReference flag should be in [....]; hitting this may mean that it's time to divide the DeferredReference flag into a set of flags, one for each modifier"); return entry; } internal void SetAnimationBaseValue(object animationBaseValue) { if (!HasModifiers) { Value = animationBaseValue; } else { ModifiedValue modifiedValue = ModifiedValue; if (IsExpression) { modifiedValue.ExpressionValue = animationBaseValue; } else { modifiedValue.BaseValue = animationBaseValue; } //the modified value may be a deferred reference so recompute this flag. ComputeIsDeferred(); } } internal void SetCoersionBaseValue(object coersionBaseValue) { if (!HasModifiers) { Value = coersionBaseValue; } else { ModifiedValue modifiedValue = ModifiedValue; if (IsAnimated) { modifiedValue.AnimatedValue = coersionBaseValue; } else if (IsExpression) { modifiedValue.ExpressionValue = coersionBaseValue; } else { modifiedValue.BaseValue = coersionBaseValue; } //the modified value may be a deferred reference so recompute this flag. ComputeIsDeferred(); } } internal object LocalValue { get { if (BaseValueSourceInternal == BaseValueSourceInternal.Local) { if (!HasModifiers) { Debug.Assert(Value != DependencyProperty.UnsetValue); return Value; } else { Debug.Assert(ModifiedValue != null && ModifiedValue.BaseValue != DependencyProperty.UnsetValue); return ModifiedValue.BaseValue; } } else { return DependencyProperty.UnsetValue; } } set { Debug.Assert(BaseValueSourceInternal == BaseValueSourceInternal.Local, "This can happen only on an entry already having a local value"); if (!HasModifiers) { Debug.Assert(Value != DependencyProperty.UnsetValue); Value = value; } else { Debug.Assert(ModifiedValue != null && ModifiedValue.BaseValue != DependencyProperty.UnsetValue); ModifiedValue.BaseValue = value; } } } internal ModifiedValue ModifiedValue { get { if (_value != null) { return _value as ModifiedValue; } return null; } } private ModifiedValue EnsureModifiedValue() { ModifiedValue modifiedValue = null; if (_value == null) { _value = modifiedValue = new ModifiedValue(); } else { modifiedValue = _value as ModifiedValue; if (modifiedValue == null) { modifiedValue = new ModifiedValue(); modifiedValue.BaseValue = _value; _value = modifiedValue; } } return modifiedValue; } internal void Clear() { _propertyIndex = -1; _value = null; _source = 0; } #endregion InternalProperties #region PrivateMethods private void WritePrivateFlag(FullValueSource bit, bool value) { if (value) { _source |= bit; } else { _source &= ~bit; } } private bool ReadPrivateFlag(FullValueSource bit) { return (_source & bit) != 0; } #endregion PrivateMethods #region Data private object _value; private short _propertyIndex; private FullValueSource _source; #endregion Data } [FriendAccessAllowed] // Built into Base, also used by Core & Framework. internal enum FullValueSource : short { // Bit used to store BaseValueSourceInternal = 0x01 // Bit used to store BaseValueSourceInternal = 0x02 // Bit used to store BaseValueSourceInternal = 0x04 // Bit used to store BaseValueSourceInternal = 0x08 ValueSourceMask = 0x000F, ModifiersMask = 0x0070, IsExpression = 0x0010, IsAnimated = 0x0020, IsCoerced = 0x0040, IsPotentiallyADeferredReference = 0x0080, HasExpressionMarker = 0x0100, IsCoercedWithCurrentValue = 0x200, } // Note that these enum values are arranged in the reverse order of // precendence for these sources. Local value has highest // precedence and Default value has the least. Note that we do not // store default values in the _effectiveValues cache unless it is // being coerced/animated. [FriendAccessAllowed] // Built into Base, also used by Core & Framework. internal enum BaseValueSourceInternal : short { Unknown = 0, Default = 1, Inherited = 2, ThemeStyle = 3, ThemeStyleTrigger = 4, Style = 5, TemplateTrigger = 6, StyleTrigger = 7, ImplicitReference = 8, ParentTemplate = 9, ParentTemplateTrigger = 10, Local = 11, } [FriendAccessAllowed] // Built into Base, also used by Core & Framework. internal class ModifiedValue { #region InternalProperties internal object BaseValue { get { return _baseValue; } set { _baseValue = value; } } internal object ExpressionValue { get { return _expressionValue; } set { _expressionValue = value; } } internal object AnimatedValue { get { return _animatedValue; } set { _animatedValue = value; } } internal object CoercedValue { get { return _coercedValue; } set { _coercedValue = value; } } #endregion InternalProperties #region Data private object _baseValue; private object _expressionValue; private object _animatedValue; private object _coercedValue; #endregion Data } } // 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
- TileBrush.cs
- EdmConstants.cs
- Win32PrintDialog.cs
- StreamingContext.cs
- FontCollection.cs
- VirtualizedItemProviderWrapper.cs
- RawMouseInputReport.cs
- followingquery.cs
- AnimationClock.cs
- TextServicesProperty.cs
- DeferredRunTextReference.cs
- SRGSCompiler.cs
- Decoder.cs
- IndexedGlyphRun.cs
- XpsThumbnail.cs
- CodeVariableDeclarationStatement.cs
- TrackBar.cs
- RectAnimation.cs
- SqlTypeSystemProvider.cs
- Enlistment.cs
- TextEditorLists.cs
- FrameworkContentElement.cs
- ProcessModule.cs
- HashAlgorithm.cs
- Flattener.cs
- TreeWalkHelper.cs
- CodeDomDesignerLoader.cs
- FixedTextPointer.cs
- EmptyImpersonationContext.cs
- BitmapEffectGeneralTransform.cs
- BindingManagerDataErrorEventArgs.cs
- SqlSelectStatement.cs
- EventProvider.cs
- MenuItemCollection.cs
- FilteredXmlReader.cs
- ParagraphVisual.cs
- AtomParser.cs
- CodeConditionStatement.cs
- EastAsianLunisolarCalendar.cs
- FixedPageAutomationPeer.cs
- TextViewBase.cs
- SafeLibraryHandle.cs
- ValueProviderWrapper.cs
- PartitionerStatic.cs
- OperatorExpressions.cs
- RowBinding.cs
- CompositeFontFamily.cs
- TimelineGroup.cs
- DBConnection.cs
- FontSource.cs
- DoubleAnimationClockResource.cs
- XmlReflectionImporter.cs
- ApplicationHost.cs
- WindowsListViewScroll.cs
- ControlBuilderAttribute.cs
- TemplateLookupAction.cs
- RayHitTestParameters.cs
- CreateParams.cs
- FontDifferentiator.cs
- SHA384Cng.cs
- backend.cs
- CompilationSection.cs
- ComponentEditorPage.cs
- WebControl.cs
- DataObjectFieldAttribute.cs
- cache.cs
- SmiEventSink.cs
- PropertySegmentSerializer.cs
- BaseResourcesBuildProvider.cs
- CompositeDuplexBindingElementImporter.cs
- GlyphRunDrawing.cs
- SymmetricSecurityProtocolFactory.cs
- DataStreamFromComStream.cs
- formatter.cs
- FixedTextPointer.cs
- querybuilder.cs
- ErrorLog.cs
- ModulesEntry.cs
- SessionPageStateSection.cs
- ConfigXmlAttribute.cs
- EmbeddedMailObjectsCollection.cs
- FacetValues.cs
- WebExceptionStatus.cs
- Axis.cs
- DiagnosticTrace.cs
- PathTooLongException.cs
- KeyInterop.cs
- DataGridViewButtonColumn.cs
- ContainerUtilities.cs
- EntityViewGenerationConstants.cs
- InfoCardSymmetricCrypto.cs
- EmptyEnumerator.cs
- DocumentOutline.cs
- FrameworkElement.cs
- FlowDocumentReaderAutomationPeer.cs
- TokenizerHelper.cs
- ServiceBuildProvider.cs
- DurationConverter.cs
- GenerateHelper.cs
- ScriptRegistrationManager.cs