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
- GroupDescription.cs
- CompilerErrorCollection.cs
- MultilineStringEditor.cs
- XsdDataContractExporter.cs
- ResourceDescriptionAttribute.cs
- UnsafeNativeMethods.cs
- TextEditorTyping.cs
- CommandHelper.cs
- ScriptManagerProxy.cs
- TileModeValidation.cs
- AccessDataSourceView.cs
- FunctionDescription.cs
- TableStyle.cs
- QuaternionRotation3D.cs
- FamilyCollection.cs
- CodeParameterDeclarationExpressionCollection.cs
- ParserStreamGeometryContext.cs
- JsonObjectDataContract.cs
- Compiler.cs
- PointUtil.cs
- _Win32.cs
- SemanticKeyElement.cs
- SamlAuthorityBinding.cs
- WeakRefEnumerator.cs
- Viewport3DVisual.cs
- RequestNavigateEventArgs.cs
- HandleValueEditor.cs
- DBCSCodePageEncoding.cs
- FixedSOMTableRow.cs
- TabletDeviceInfo.cs
- SystemIPInterfaceStatistics.cs
- ValuePatternIdentifiers.cs
- altserialization.cs
- ProcessStartInfo.cs
- DispatchChannelSink.cs
- ADConnectionHelper.cs
- IdentitySection.cs
- ApplicationFileCodeDomTreeGenerator.cs
- TypeConverterHelper.cs
- SqlDataSourceView.cs
- messageonlyhwndwrapper.cs
- ZoneButton.cs
- ComponentRenameEvent.cs
- StructureChangedEventArgs.cs
- DeploymentExceptionMapper.cs
- RegexTree.cs
- WindowsRichEdit.cs
- ClientConfigurationHost.cs
- RoutedEventConverter.cs
- FieldMetadata.cs
- TextEditorParagraphs.cs
- XmlHierarchicalDataSourceView.cs
- SQLInt16.cs
- HttpCapabilitiesSectionHandler.cs
- Token.cs
- DataReaderContainer.cs
- BitmapData.cs
- UnmanagedMemoryStreamWrapper.cs
- Dump.cs
- Module.cs
- TypeTypeConverter.cs
- SortedDictionary.cs
- DefaultMergeHelper.cs
- ImageKeyConverter.cs
- DataMisalignedException.cs
- UmAlQuraCalendar.cs
- XmlDocumentSerializer.cs
- ProtocolsConfigurationHandler.cs
- UnsafeMethods.cs
- SweepDirectionValidation.cs
- ProviderCollection.cs
- WriteLine.cs
- Point3D.cs
- BrowserCapabilitiesCodeGenerator.cs
- XmlWrappingWriter.cs
- ProbeDuplexAsyncResult.cs
- TextSelectionHighlightLayer.cs
- TextSpanModifier.cs
- LambdaCompiler.Binary.cs
- SessionStateUtil.cs
- BuildManagerHost.cs
- ClientEventManager.cs
- DataControlFieldCell.cs
- SafeThemeHandle.cs
- Content.cs
- DbTransaction.cs
- TraversalRequest.cs
- Helpers.cs
- SafeRegistryKey.cs
- SmtpTransport.cs
- Automation.cs
- CodeTypeParameterCollection.cs
- ModifierKeysConverter.cs
- PropertyEntry.cs
- BinHexDecoder.cs
- SafeProcessHandle.cs
- ProgressBarAutomationPeer.cs
- XmlSchemaComplexContent.cs
- CompilerErrorCollection.cs
- XmlDictionaryReader.cs