TemplateApplicationHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / Markup / TemplateApplicationHelper.cs / 2 / TemplateApplicationHelper.cs

                            /****************************************************************************\ 
*
* File: TemplateApplicationHelper.cs
*
* Copyright (C) 2005 by Microsoft Corporation.  All rights reserved. 
*
\***************************************************************************/ 
 

using MS.Internal; 
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Markup; 
using System.Windows.Data;
using System.Windows.Documents; 
using System.Windows.Controls; 
using System.Collections.Specialized;
 

namespace System.Windows
{
    //+--------------------------------------------------------------------------------------------- 
    //
    //  Class TemplateApplicationHelper 
    // 
    //  This class is a BamlRecordReader which is used to help instantiate a template.
    //  This BamlRecordReader is used to instantiate the unshareable content of the template, 
    //  and we override SetDependencyValue here so that we can set values into
    //  the FE's special store for ParentTemplate values.
    //
    //+--------------------------------------------------------------------------------------------- 

    internal class TemplateApplicationHelper : BamlRecordReader 
    { 
        internal TemplateApplicationHelper ( )
        { 
            RootList = new ArrayList(1);
        }

        // 
        // Initialization is separate from the constructer so that it can be called
        // repeatedly. 
        // 

        internal void Initialize( ParserContext parserContext, object templatedParent  ) 
        {
            ParserContext = parserContext;
            _templatedParent = (DependencyObject) templatedParent;
 
            RootElement = null;
 
            if( RootList != null ) 
            {
                RootList.Clear(); 
            }

            ContextStack.Clear();
 
            ComponentConnector = null;
        } 
 
        /***************************************************************************\
        * 
        * TemplateBamlRecordReader.ReadDeferableContentStart
        *
        * Called when parsing the deferable content start element.
        * When we have a ResourceDictionary inside template content, 
        * we need to retrieve the cached values buffer and supply it
        * do the ResourceDictionary so that it can use it to 
        * RealizeDeferredContent. 
        *
        \***************************************************************************/ 

        internal override void ReadDeferableContentStart(
            BamlDeferableContentStartRecord bamlRecord)
        { 
            ResourceDictionary dictionary = GetDictionaryFromContext(CurrentContext, true /*toInsert*/) as ResourceDictionary;
 
            if (dictionary != null) 
            {
                // Read and create the keys and the static resource 
                // objects for this dictionary

                ArrayList       defKeyList;
                List  staticResourceValuesList; 
                BaseReadDeferableContentStart(bamlRecord, out defKeyList, out staticResourceValuesList);
 
                // Supply the keys, static resources and values buffer to the 
                // dictionary so it can use it to realize deferred content.
 
                dictionary.SetDeferableContent(bamlRecord.ValuesBuffer, ParserContext, RootElement, defKeyList, staticResourceValuesList);
            }
        }
 

        //+------------------------------------------------------------------------------------------------------------ 
        // 
        //  SetDependencyValue (override)
        // 
        //  If a DP value is being set onto an FE/FCE that is being optimized as part of a template, put the
        //  value into the special ParentTemplate state.
        //
        //+----------------------------------------------------------------------------------------------------------- 

        internal override void SetDependencyValueCore(DependencyObject dependencyObject, DependencyProperty dp, object value ) 
        { 
            FrameworkObject fo = new FrameworkObject(dependencyObject);
 
            // If this isn't an FE that we're optimizing, defer to base.
            //
            // Similarly, if we don't have a templated parent, we're not optimizing, and defer to base
            // (This happens when FrameworkTemplate.LoadContent() is called.) 

            if ((fo.TemplatedParent == null) || ( _templatedParent == null )) 
            { 
                base.SetDependencyValueCore( dependencyObject, dp, value );
                return; 
            }

            // For template content, we skip the automatic BaseUriProperty and the UidProperty
            // (Implementation note:  Doing this here because this is what we did with FEFs, 
            // and because automation gets confused if the Uid isn't unique in the whole tree).
 
            if( dp == System.Windows.Navigation.BaseUriHelper.BaseUriProperty ) 
            {
                // We only skip the automatic BaseUri property.  If it's set explicitely, 
                // that's passed through.

                if (!fo.IsInitialized)
                { 
                    return;
                } 
            } 

            else if (dp == UIElement.UidProperty) 
            {
                return;
            }
 

            #if DEBUG 
            Debug.Assert(fo.TemplatedParent == _templatedParent); 
            #endif
 
            // Set the value onto the FE/FCE.


            HybridDictionary parentTemplateValues; 
            if (!fo.StoresParentTemplateValues)
            { 
                parentTemplateValues = new HybridDictionary(); 
                StyleHelper.ParentTemplateValuesField.SetValue(dependencyObject, parentTemplateValues);
                fo.StoresParentTemplateValues = true; 
            }
            else
            {
                parentTemplateValues = StyleHelper.ParentTemplateValuesField.GetValue(dependencyObject); 
            }
 
            // Check if it is an expression 

            Expression expr; 
            int childIndex = fo.TemplateChildIndex;


            if ((expr = value as Expression) != null) 
            {
                BindingExpressionBase bindingExpr; 
                TemplateBindingExpression templateBindingExpr; 

                if ((bindingExpr = expr as BindingExpressionBase) != null) 
                {
                    // If this is a BindingExpression then we need to store the corresponding
                    // MarkupExtension into the per instance store for the unshared DP value.
 
                    // Allocate a slot for this unshared DP value in the per-instance store for MarkupExtensions
 
                    HybridDictionary instanceValues = StyleHelper.EnsureInstanceData(StyleHelper.TemplateDataField, _templatedParent, InstanceStyleData.InstanceValues); 
                    StyleHelper.ProcessInstanceValue(dependencyObject, childIndex, instanceValues, dp, StyleHelper.UnsharedTemplateContentPropertyIndex, true /*apply*/);
 
                    value = bindingExpr.ParentBindingBase;
                }
                else if ((templateBindingExpr = expr as TemplateBindingExpression) != null)
                { 
                    // If this is a TemplateBindingExpression then we create an equivalent Binding
                    // MarkupExtension and store that in the per instance store for the unshared DP 
                    // value. We use Binding here because it has all the wiring in place to handle 
                    // change notifications through DependencySource and such.
 
                    TemplateBindingExtension templateBindingExtension = templateBindingExpr.TemplateBindingExtension;

                    // Allocate a slot for this unshared DP value in the per-instance store for MarkupExtensions
 
                    HybridDictionary instanceValues = StyleHelper.EnsureInstanceData(StyleHelper.TemplateDataField, _templatedParent, InstanceStyleData.InstanceValues);
                    StyleHelper.ProcessInstanceValue(dependencyObject, childIndex, instanceValues, dp, StyleHelper.UnsharedTemplateContentPropertyIndex, true /*apply*/); 
 
                    // Create a Binding equivalent to the TemplateBindingExtension
 
                    Binding binding = new Binding();
                    binding.Mode = BindingMode.OneWay;
                    binding.RelativeSource = RelativeSource.TemplatedParent;
                    binding.Path = new PropertyPath(templateBindingExtension.Property); 
                    binding.Converter = templateBindingExtension.Converter;
                    binding.ConverterParameter = templateBindingExtension.ConverterParameter; 
 
                    value = binding;
 
                }
                else
                {
                    Debug.Assert(false, "We do not have support for DynamicResource within unshared template content"); 
                }
            } 
 
            bool isMarkupExtension = value is MarkupExtension;
            // Value needs to be valid for the DP, or Binding/MultiBinding/PriorityBinding/TemplateBinding. 
            if (!dp.IsValidValue(value))
            {
                if (!isMarkupExtension && !(value is DeferredReference))
                { 
                    throw new ArgumentException(SR.Get(SRID.InvalidPropertyValue, value, dp.Name));
                } 
            } 

            parentTemplateValues[dp] = value; 

            dependencyObject.ProvideSelfAsInheritanceContext( value, dp );

            EffectiveValueEntry entry = new EffectiveValueEntry(dp); 
            entry.BaseValueSourceInternal = BaseValueSourceInternal.ParentTemplate;
            entry.Value = value; 
 
            if (isMarkupExtension)
            { 
                // entry will be updated to hold the value
                StyleHelper.GetInstanceValue(
                            StyleHelper.TemplateDataField,
                            _templatedParent, 
                            fo.FE,
                            fo.FCE, 
                            childIndex, 
                            dp,
                            StyleHelper.UnsharedTemplateContentPropertyIndex, 
                            ref entry);
            }

            dependencyObject.UpdateEffectiveValue( 
                    dependencyObject.LookupEntry(dp.GlobalIndex),
                    dp, 
                    dp.GetMetadata(dependencyObject.DependencyObjectType), 
                    new EffectiveValueEntry() /* oldEntry */,
                ref entry, 
                    false /* coerceWithDeferredReference */,
                    OperationType.Unknown);
        }
 
        // Since TemplateBinding can only be used in Templates this is overridden and
        // specifically handled here. 
        internal override object GetExtensionValue( 
            IOptimizedMarkupExtension optimizedMarkupExtensionRecord,
            string                    propertyName) 
        {
            object valueObject = null;
            short extensionTypeId = optimizedMarkupExtensionRecord.ExtensionTypeId;
 
            if (extensionTypeId == (short)KnownElements.TemplateBindingExtension)
            { 
                short memberId = optimizedMarkupExtensionRecord.ValueId; 
                DependencyProperty dp = MapTable.GetDependencyPropertyValueFromId(memberId);
                if (dp != null) 
                {
                    valueObject = new TemplateBindingExtension(dp);
                }
                else 
                {
                    ThrowException(SRID.ParserCannotConvertPropertyValue, 
                                   propertyName, 
                                   typeof(TemplateBindingExtension).FullName);
                } 
            }
            else
            {
                valueObject = base.GetExtensionValue(optimizedMarkupExtensionRecord, propertyName); 
            }
 
            return valueObject; 
        }
 
        private DependencyObject _templatedParent;
    }
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/****************************************************************************\ 
*
* File: TemplateApplicationHelper.cs
*
* Copyright (C) 2005 by Microsoft Corporation.  All rights reserved. 
*
\***************************************************************************/ 
 

using MS.Internal; 
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Markup; 
using System.Windows.Data;
using System.Windows.Documents; 
using System.Windows.Controls; 
using System.Collections.Specialized;
 

namespace System.Windows
{
    //+--------------------------------------------------------------------------------------------- 
    //
    //  Class TemplateApplicationHelper 
    // 
    //  This class is a BamlRecordReader which is used to help instantiate a template.
    //  This BamlRecordReader is used to instantiate the unshareable content of the template, 
    //  and we override SetDependencyValue here so that we can set values into
    //  the FE's special store for ParentTemplate values.
    //
    //+--------------------------------------------------------------------------------------------- 

    internal class TemplateApplicationHelper : BamlRecordReader 
    { 
        internal TemplateApplicationHelper ( )
        { 
            RootList = new ArrayList(1);
        }

        // 
        // Initialization is separate from the constructer so that it can be called
        // repeatedly. 
        // 

        internal void Initialize( ParserContext parserContext, object templatedParent  ) 
        {
            ParserContext = parserContext;
            _templatedParent = (DependencyObject) templatedParent;
 
            RootElement = null;
 
            if( RootList != null ) 
            {
                RootList.Clear(); 
            }

            ContextStack.Clear();
 
            ComponentConnector = null;
        } 
 
        /***************************************************************************\
        * 
        * TemplateBamlRecordReader.ReadDeferableContentStart
        *
        * Called when parsing the deferable content start element.
        * When we have a ResourceDictionary inside template content, 
        * we need to retrieve the cached values buffer and supply it
        * do the ResourceDictionary so that it can use it to 
        * RealizeDeferredContent. 
        *
        \***************************************************************************/ 

        internal override void ReadDeferableContentStart(
            BamlDeferableContentStartRecord bamlRecord)
        { 
            ResourceDictionary dictionary = GetDictionaryFromContext(CurrentContext, true /*toInsert*/) as ResourceDictionary;
 
            if (dictionary != null) 
            {
                // Read and create the keys and the static resource 
                // objects for this dictionary

                ArrayList       defKeyList;
                List  staticResourceValuesList; 
                BaseReadDeferableContentStart(bamlRecord, out defKeyList, out staticResourceValuesList);
 
                // Supply the keys, static resources and values buffer to the 
                // dictionary so it can use it to realize deferred content.
 
                dictionary.SetDeferableContent(bamlRecord.ValuesBuffer, ParserContext, RootElement, defKeyList, staticResourceValuesList);
            }
        }
 

        //+------------------------------------------------------------------------------------------------------------ 
        // 
        //  SetDependencyValue (override)
        // 
        //  If a DP value is being set onto an FE/FCE that is being optimized as part of a template, put the
        //  value into the special ParentTemplate state.
        //
        //+----------------------------------------------------------------------------------------------------------- 

        internal override void SetDependencyValueCore(DependencyObject dependencyObject, DependencyProperty dp, object value ) 
        { 
            FrameworkObject fo = new FrameworkObject(dependencyObject);
 
            // If this isn't an FE that we're optimizing, defer to base.
            //
            // Similarly, if we don't have a templated parent, we're not optimizing, and defer to base
            // (This happens when FrameworkTemplate.LoadContent() is called.) 

            if ((fo.TemplatedParent == null) || ( _templatedParent == null )) 
            { 
                base.SetDependencyValueCore( dependencyObject, dp, value );
                return; 
            }

            // For template content, we skip the automatic BaseUriProperty and the UidProperty
            // (Implementation note:  Doing this here because this is what we did with FEFs, 
            // and because automation gets confused if the Uid isn't unique in the whole tree).
 
            if( dp == System.Windows.Navigation.BaseUriHelper.BaseUriProperty ) 
            {
                // We only skip the automatic BaseUri property.  If it's set explicitely, 
                // that's passed through.

                if (!fo.IsInitialized)
                { 
                    return;
                } 
            } 

            else if (dp == UIElement.UidProperty) 
            {
                return;
            }
 

            #if DEBUG 
            Debug.Assert(fo.TemplatedParent == _templatedParent); 
            #endif
 
            // Set the value onto the FE/FCE.


            HybridDictionary parentTemplateValues; 
            if (!fo.StoresParentTemplateValues)
            { 
                parentTemplateValues = new HybridDictionary(); 
                StyleHelper.ParentTemplateValuesField.SetValue(dependencyObject, parentTemplateValues);
                fo.StoresParentTemplateValues = true; 
            }
            else
            {
                parentTemplateValues = StyleHelper.ParentTemplateValuesField.GetValue(dependencyObject); 
            }
 
            // Check if it is an expression 

            Expression expr; 
            int childIndex = fo.TemplateChildIndex;


            if ((expr = value as Expression) != null) 
            {
                BindingExpressionBase bindingExpr; 
                TemplateBindingExpression templateBindingExpr; 

                if ((bindingExpr = expr as BindingExpressionBase) != null) 
                {
                    // If this is a BindingExpression then we need to store the corresponding
                    // MarkupExtension into the per instance store for the unshared DP value.
 
                    // Allocate a slot for this unshared DP value in the per-instance store for MarkupExtensions
 
                    HybridDictionary instanceValues = StyleHelper.EnsureInstanceData(StyleHelper.TemplateDataField, _templatedParent, InstanceStyleData.InstanceValues); 
                    StyleHelper.ProcessInstanceValue(dependencyObject, childIndex, instanceValues, dp, StyleHelper.UnsharedTemplateContentPropertyIndex, true /*apply*/);
 
                    value = bindingExpr.ParentBindingBase;
                }
                else if ((templateBindingExpr = expr as TemplateBindingExpression) != null)
                { 
                    // If this is a TemplateBindingExpression then we create an equivalent Binding
                    // MarkupExtension and store that in the per instance store for the unshared DP 
                    // value. We use Binding here because it has all the wiring in place to handle 
                    // change notifications through DependencySource and such.
 
                    TemplateBindingExtension templateBindingExtension = templateBindingExpr.TemplateBindingExtension;

                    // Allocate a slot for this unshared DP value in the per-instance store for MarkupExtensions
 
                    HybridDictionary instanceValues = StyleHelper.EnsureInstanceData(StyleHelper.TemplateDataField, _templatedParent, InstanceStyleData.InstanceValues);
                    StyleHelper.ProcessInstanceValue(dependencyObject, childIndex, instanceValues, dp, StyleHelper.UnsharedTemplateContentPropertyIndex, true /*apply*/); 
 
                    // Create a Binding equivalent to the TemplateBindingExtension
 
                    Binding binding = new Binding();
                    binding.Mode = BindingMode.OneWay;
                    binding.RelativeSource = RelativeSource.TemplatedParent;
                    binding.Path = new PropertyPath(templateBindingExtension.Property); 
                    binding.Converter = templateBindingExtension.Converter;
                    binding.ConverterParameter = templateBindingExtension.ConverterParameter; 
 
                    value = binding;
 
                }
                else
                {
                    Debug.Assert(false, "We do not have support for DynamicResource within unshared template content"); 
                }
            } 
 
            bool isMarkupExtension = value is MarkupExtension;
            // Value needs to be valid for the DP, or Binding/MultiBinding/PriorityBinding/TemplateBinding. 
            if (!dp.IsValidValue(value))
            {
                if (!isMarkupExtension && !(value is DeferredReference))
                { 
                    throw new ArgumentException(SR.Get(SRID.InvalidPropertyValue, value, dp.Name));
                } 
            } 

            parentTemplateValues[dp] = value; 

            dependencyObject.ProvideSelfAsInheritanceContext( value, dp );

            EffectiveValueEntry entry = new EffectiveValueEntry(dp); 
            entry.BaseValueSourceInternal = BaseValueSourceInternal.ParentTemplate;
            entry.Value = value; 
 
            if (isMarkupExtension)
            { 
                // entry will be updated to hold the value
                StyleHelper.GetInstanceValue(
                            StyleHelper.TemplateDataField,
                            _templatedParent, 
                            fo.FE,
                            fo.FCE, 
                            childIndex, 
                            dp,
                            StyleHelper.UnsharedTemplateContentPropertyIndex, 
                            ref entry);
            }

            dependencyObject.UpdateEffectiveValue( 
                    dependencyObject.LookupEntry(dp.GlobalIndex),
                    dp, 
                    dp.GetMetadata(dependencyObject.DependencyObjectType), 
                    new EffectiveValueEntry() /* oldEntry */,
                ref entry, 
                    false /* coerceWithDeferredReference */,
                    OperationType.Unknown);
        }
 
        // Since TemplateBinding can only be used in Templates this is overridden and
        // specifically handled here. 
        internal override object GetExtensionValue( 
            IOptimizedMarkupExtension optimizedMarkupExtensionRecord,
            string                    propertyName) 
        {
            object valueObject = null;
            short extensionTypeId = optimizedMarkupExtensionRecord.ExtensionTypeId;
 
            if (extensionTypeId == (short)KnownElements.TemplateBindingExtension)
            { 
                short memberId = optimizedMarkupExtensionRecord.ValueId; 
                DependencyProperty dp = MapTable.GetDependencyPropertyValueFromId(memberId);
                if (dp != null) 
                {
                    valueObject = new TemplateBindingExtension(dp);
                }
                else 
                {
                    ThrowException(SRID.ParserCannotConvertPropertyValue, 
                                   propertyName, 
                                   typeof(TemplateBindingExtension).FullName);
                } 
            }
            else
            {
                valueObject = base.GetExtensionValue(optimizedMarkupExtensionRecord, propertyName); 
            }
 
            return valueObject; 
        }
 
        private DependencyObject _templatedParent;
    }
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK