ContentPresenter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / System / Windows / Controls / ContentPresenter.cs / 4 / ContentPresenter.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: ContentPresenter class 
// 
// Specs:       [....]/connecteddata/M5%20General%20Docs/Data%20Styling.mht
// 
//---------------------------------------------------------------------------

using System;
using System.Diagnostics; 
using System.ComponentModel;
 
using System.Windows.Threading; 

using System.Windows.Shapes; 
using System.Windows.Media;
using System.Windows.Data;
using System.Windows.Markup;
using MS.Internal; 
using MS.Internal.Data;
using MS.Internal.KnownBoxes; 
using System.Windows.Documents; 

using MS.Utility; 
using MS.Internal.PresentationFramework;

namespace System.Windows.Controls
{ 
    /// 
    /// ContentPresenter is used within the template of a content control to denote the 
    /// place in the control's visual tree (control template) where the content 
    /// is to be added.
    ///  
    [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)]
    public class ContentPresenter : FrameworkElement
    {
        //----------------------------------------------------- 
        //
        //  Constructors 
        // 
        //-----------------------------------------------------
 
        static ContentPresenter()
        {
            DataTemplate template;
            FrameworkElementFactory text; 
            Binding binding;
 
            // Default template for strings when hosted in ContentPresener with RecognizesAccessKey=true 
            template = new DataTemplate();
            text = CreateAccessTextFactory(); 
            text.SetValue(AccessText.TextProperty, new TemplateBindingExtension(ContentProperty));
            template.VisualTree = text;
            template.Seal();
            s_AccessTextTemplate = template; 

            // Default template for strings 
            template = new DataTemplate(); 
            text = CreateTextBlockFactory();
            text.SetValue(TextBlock.TextProperty, new TemplateBindingExtension(ContentProperty)); 
            template.VisualTree = text;
            template.Seal();
            s_StringTemplate = template;
 
            // Default template for XmlNodes
            template = new DataTemplate(); 
            text = CreateTextBlockFactory(); 
            binding = new Binding();
            binding.XPath = "."; 
            text.SetBinding(TextBlock.TextProperty, binding);
            template.VisualTree = text;
            template.Seal();
            s_XmlNodeTemplate = template; 

            // Default template for UIElements 
            template = new UseContentTemplate(); 
            template.Seal();
            s_UIElementTemplate = template; 

            // Default template for everything else
            template = new DefaultTemplate();
            template.Seal(); 
            s_DefaultTemplate = template;
 
            // Default template selector 
            s_DefaultTemplateSelector = new DefaultSelector();
        } 


        /// 
        ///     Default constructor 
        /// 
        ///  
        ///     Automatic determination of current Dispatcher. Use alternative constructor 
        ///     that accepts a Dispatcher for best performance.
        ///  
        public ContentPresenter() : base()
        {
            Initialize();
        } 

        void Initialize() 
        { 
            // Initialize the _templateCache to the default value for TemplateProperty.
            // If the default value is non-null then wire it to the current instance. 
            PropertyMetadata metadata = TemplateProperty.GetMetadata(DependencyObjectType);
            DataTemplate defaultValue = (DataTemplate) metadata.DefaultValue;
            if (defaultValue != null)
            { 
                OnTemplateChanged(this, new DependencyPropertyChangedEventArgs(TemplateProperty, metadata, null, defaultValue));
            } 
 
            DataContext = null; // this presents a uniform view:  CP always has local DC
        } 

        //------------------------------------------------------
        //
        //  Public Properties 
        //
        //----------------------------------------------------- 
 

        ///  
        ///     The DependencyProperty for the RecognizesAccessKey property.
        ///     Flags:              None
        ///     Default Value:      false
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty RecognizesAccessKeyProperty = 
                DependencyProperty.Register( 
                        "RecognizesAccessKey",
                        typeof(bool), 
                        typeof(ContentPresenter),
                        new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));

        ///  
        ///     Determine if ContentPresenter should use AccessText in its style
        ///  
        public bool RecognizesAccessKey 
        {
            get { return (bool) GetValue(RecognizesAccessKeyProperty); } 
            set { SetValue(RecognizesAccessKeyProperty, BooleanBoxes.Box(value)); }
        }

        ///  
        ///     The DependencyProperty for the Content property.
        ///     Flags:              None 
        ///     Default Value:      null 
        /// 
        // Any change in Content properties affectes layout measurement since 
        // a new template may be used. On measurement,
        // ApplyTemplate will be invoked leading to possible application
        // of a new template.
        [CommonDependencyProperty] 
        public static readonly DependencyProperty ContentProperty =
                ContentControl.ContentProperty.AddOwner( 
                        typeof(ContentPresenter), 
                        new FrameworkPropertyMetadata(
                            (object)null, 
                            FrameworkPropertyMetadataOptions.AffectsMeasure,
                            new PropertyChangedCallback(OnContentChanged)));

        ///  
        ///     Content is the data used to generate the child elements of this control.
        ///  
        public object Content 
        {
            get { return GetValue(ContentControl.ContentProperty); } 
            set { SetValue(ContentControl.ContentProperty, value); }
        }

        ///  
        ///     Called when ContentProperty is invalidated on "d."
        ///  
        private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            ContentPresenter ctrl = (ContentPresenter)d; 

            bool mismatch;

            if (ctrl.ContentTemplate != null) 
            {
                mismatch = false;       // explicit template - matches by fiat 
            } 
            else if (ctrl.ContentTemplateSelector != null)
            { 
                mismatch = true;        // template selector - always re-select
            }
            else if (ctrl.Template == UIElementContentTemplate ||
                    ctrl.Template == DefaultContentTemplate) 
            {
                mismatch = true;        // direct template - always re-apply 
            } 
            else
            { 
                // type-based template - matches if types agree
                Type oldType = (e.OldValue != null) ? e.OldValue.GetType() : null;
                Type newType = (e.NewValue != null) ? e.NewValue.GetType() : null;
                mismatch = (oldType != newType); 
            }
 
            // if the content and (old) template don't match, get rid of the template 
            if (mismatch)
            { 
                ctrl._templateIsCurrent = false;
                ctrl.Template = null;
            }
 
            // keep the DataContext in sync with Content
            if (ctrl._templateIsCurrent && ctrl.Template != UIElementContentTemplate) 
            { 
                ctrl.DataContext = e.NewValue;
            } 
        }


        ///  
        ///     The DependencyProperty for the ContentTemplate property.
        ///     Flags:              None 
        ///     Default Value:      null 
        /// 
        [CommonDependencyProperty] 
        public static readonly DependencyProperty ContentTemplateProperty =
                ContentControl.ContentTemplateProperty.AddOwner(
                        typeof(ContentPresenter),
                        new FrameworkPropertyMetadata( 
                                (DataTemplate)null,
                                FrameworkPropertyMetadataOptions.AffectsMeasure, 
                                new PropertyChangedCallback(OnContentTemplateChanged))); 

        ///  
        ///     ContentTemplate is the template used to display the content of the control.
        /// 
        public DataTemplate ContentTemplate
        { 
            get { return (DataTemplate) GetValue(ContentControl.ContentTemplateProperty); }
            set { SetValue(ContentControl.ContentTemplateProperty, value); } 
        } 

        ///  
        ///     Called when ContentTemplateProperty is invalidated on "d."
        /// 
        private static void OnContentTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            ContentPresenter ctrl = (ContentPresenter)d;
            ctrl._templateIsCurrent = false; 
            ctrl.OnContentTemplateChanged((DataTemplate) e.OldValue, (DataTemplate) e.NewValue); 
        }
 
        /// 
        ///     This method is invoked when the ContentTemplate property changes.
        /// 
        /// The old value of the ContentTemplate property. 
        /// The new value of the ContentTemplate property.
        protected virtual void OnContentTemplateChanged(DataTemplate oldContentTemplate, DataTemplate newContentTemplate) 
        { 
            Helper.CheckTemplateAndTemplateSelector("Content", ContentTemplateProperty, ContentTemplateSelectorProperty, this);
 
            // if ContentTemplate is really changing, remove the old template
            this.Template = null;
        }
 

        ///  
        ///     The DependencyProperty for the ContentTemplateSelector property. 
        ///     Flags:              None
        ///     Default Value:      null 
        /// 
        [CommonDependencyProperty]
        public static readonly DependencyProperty ContentTemplateSelectorProperty =
                ContentControl.ContentTemplateSelectorProperty.AddOwner( 
                        typeof(ContentPresenter),
                        new FrameworkPropertyMetadata( 
                                (DataTemplateSelector)null, 
                                FrameworkPropertyMetadataOptions.AffectsMeasure,
                                new PropertyChangedCallback(OnContentTemplateSelectorChanged))); 

        /// 
        ///     ContentTemplateSelector allows the application writer to provide custom logic
        ///     for choosing the template used to display the content of the control. 
        /// 
        ///  
        ///     This property is ignored if  is set. 
        /// 
        public DataTemplateSelector ContentTemplateSelector 
        {
            get { return (DataTemplateSelector) GetValue(ContentControl.ContentTemplateSelectorProperty); }
            set { SetValue(ContentControl.ContentTemplateSelectorProperty, value); }
        } 

        ///  
        /// This method is used by TypeDescriptor to determine if this property should 
        /// be serialized.
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShouldSerializeContentTemplateSelector()
        {
            return false; 
        }
 
        ///  
        ///     Called when ContentTemplateSelectorProperty is invalidated on "d."
        ///  
        private static void OnContentTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ContentPresenter ctrl = (ContentPresenter) d;
            ctrl._templateIsCurrent = false; 
            ctrl.OnContentTemplateSelectorChanged((DataTemplateSelector) e.OldValue, (DataTemplateSelector) e.NewValue);
        } 
 
        /// 
        ///     This method is invoked when the ContentTemplateSelector property changes. 
        /// 
        /// The old value of the ContentTemplateSelector property.
        /// The new value of the ContentTemplateSelector property.
        protected virtual void OnContentTemplateSelectorChanged(DataTemplateSelector oldContentTemplateSelector, DataTemplateSelector newContentTemplateSelector) 
        {
            Helper.CheckTemplateAndTemplateSelector("Content", ContentTemplateProperty, ContentTemplateSelectorProperty, this); 
 
            // if ContentTemplateSelector is really changing (and in use), remove the old template
            this.Template = null; 
        }

        /// 
        ///     The DependencyProperty for the ContentSource property. 
        ///     Flags:              None
        ///     Default Value:      Content 
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty ContentSourceProperty = 
                DependencyProperty.Register(
                        "ContentSource",
                        typeof(string),
                        typeof(ContentPresenter), 
                        new FrameworkPropertyMetadata("Content"));
 
        ///  
        ///     ContentSource is the base name to use during automatic aliasing.
        ///     When a template contains a ContentPresenter with ContentSource="Abc", 
        ///     its Content, ContentTemplate, and ContentTemplateSelector properties are
        ///     automatically aliased to Abc, AbcTemplate, and AbcTemplateSelector,
        ///     respectively.  The two most useful values for ContentSource are
        ///     "Content" and "Header";  the default is "Content". 
        /// 
        ///  
        ///     This property only makes sense in a template.  It should not be set on 
        ///     an actual ContentPresenter;  there will be no effect.
        ///  
        public string ContentSource
        {
            get { return GetValue(ContentSourceProperty) as string; }
            set { SetValue(ContentSourceProperty, value); } 
        }
 
        //------------------------------------------------------ 
        //
        //  Protected Methods 
        //
        //------------------------------------------------------

        ///  
        /// Called when the Template's tree is about to be generated
        ///  
        internal override void OnPreApplyTemplate() 
        {
            base.OnPreApplyTemplate(); 

            // If we're inflating our visual tree but our TemplatedParent is null,
            // we might have been removed from the visual tree but not have had
            // our ContentProperty invalidated.  This would mean that when we go 
            // to reparent our content, we'll be looking at a stale cache.  Make
            // sure to invalidate the Content property in this case. 
            if (TemplatedParent == null) 
            {
                // call GetValueCore to get this value from its TemplatedParent 
                InvalidateProperty(ContentProperty);
            }

            if (!_templateIsCurrent) 
            {
                EnsureTemplate(); 
                _templateIsCurrent = true; 
            }
        } 


        /// 
        /// Updates DesiredSize of the ContentPresenter.  Called by parent UIElement.  This is the first pass of layout. 
        /// 
        ///  
        /// ContentPresenter determines a desired size it needs from the child's sizing properties, margin, and requested size. 
        /// 
        /// Constraint size is an "upper limit" that the return value should not exceed. 
        /// The ContentPresenter's desired size.
        protected override Size MeasureOverride(Size constraint)
        {
            return Helper.MeasureElementWithSingleChild(this, constraint); 
        }
 
 
        /// 
        /// ContentPresenter computes the position of its single child inside child's Margin and calls Arrange 
        /// on the child.
        /// 
        /// Size the ContentPresenter will assume.
        protected override Size ArrangeOverride(Size arrangeSize) 
        {
            return Helper.ArrangeElementWithSingleChild(this, arrangeSize); 
        } 

 
        /// 
        /// Return the template to use.  This may depend on the Content, or
        /// other properties.
        ///  
        /// 
        /// The base class implements the following rules: 
        ///   (a) If ContentTemplate is set, use it. 
        ///   (b) If ContentTemplateSelector is set, call its
        ///         SelectTemplate method.  If the result is not null, use it. 
        ///   (c) Look for a DataTemplate whose DataType matches the
        ///         Content among the resources known to the ContentPresenter
        ///         (including application, theme, and system resources).
        ///         If one is found, use it. 
        ///   (d) If the type of Content is "common", use a standard template.
        ///         The common types are String, XmlNode, UIElement. 
        ///   (e) Otherwise, use a default template that essentially converts 
        ///         Content to a string and displays it in a TextBlock.
        /// Derived classes can override these rules and implement their own. 
        /// 
        protected virtual DataTemplate ChooseTemplate()
        {
            DataTemplate template = null; 
            object content = Content;
 
            // ContentTemplate has first stab 
            template = ContentTemplate;
 
            // no ContentTemplate set, try ContentTemplateSelector
            if (template == null)
            {
                if (ContentTemplateSelector != null) 
                {
                    template = ContentTemplateSelector.SelectTemplate(content, this); 
                } 
            }
 
            // if that failed, try the default TemplateSelector
            if (template == null)
            {
                template = DefaultTemplateSelector.SelectTemplate(content, this); 
            }
 
            return template; 
        }
 
        //-----------------------------------------------------
        //
        //  Internal properties
        // 
        //------------------------------------------------------
 
        internal static DataTemplate AccessTextContentTemplate 
        {
            get { return s_AccessTextTemplate; } 
        }

        internal static DataTemplate StringContentTemplate
        { 
            get { return s_StringTemplate; }
        } 
 
        // Internal Helper so the FrameworkElement could see this property
        internal override FrameworkTemplate TemplateInternal 
        {
            get { return Template; }
        }
 
        // Internal Helper so the FrameworkElement could see the template cache
        internal override FrameworkTemplate TemplateCache 
        { 
            get { return _templateCache; }
            set { _templateCache = (DataTemplate)value; } 
        }

        internal bool TemplateIsCurrent
        { 
            get { return _templateIsCurrent; }
        } 
 
        //-----------------------------------------------------
        // 
        //  Internal methods
        //
        //-----------------------------------------------------
 
        /// 
        /// Prepare to display the item. 
        ///  
        internal void PrepareContentPresenter(object item, DataTemplate itemTemplate, DataTemplateSelector itemTemplateSelector)
        { 
            if (item != this)
            {
                // copy templates from parent ItemsControl
                if (_contentIsItem || !HasNonDefaultValue(ContentProperty)) 
                {
                    Content = item; 
                    _contentIsItem = true; 
                }
                if (itemTemplate != null) 
                    SetValue(ContentTemplateProperty, itemTemplate);
                if (itemTemplateSelector != null)
                    SetValue(ContentTemplateSelectorProperty, itemTemplateSelector);
            } 
        }
 
        //----------------------------------------------------- 
        //
        //  Private properties 
        //
        //------------------------------------------------------

        static DataTemplate XmlNodeContentTemplate 
        {
            get { return s_XmlNodeTemplate; } 
        } 

        static DataTemplate UIElementContentTemplate 
        {
            get { return s_UIElementTemplate; }
        }
 
        static DataTemplate DefaultContentTemplate
        { 
            get { return s_DefaultTemplate; } 
        }
 
        static DefaultSelector DefaultTemplateSelector
        {
            get { return s_DefaultTemplateSelector; }
        } 

 
        ///  
        /// TemplateProperty
        ///  
        internal static readonly DependencyProperty TemplateProperty =
                DependencyProperty.Register(
                        "Template",
                        typeof(DataTemplate), 
                        typeof(ContentPresenter),
                        new FrameworkPropertyMetadata( 
                                (DataTemplate) null,  // default value 
                                FrameworkPropertyMetadataOptions.AffectsMeasure,
                                new PropertyChangedCallback(OnTemplateChanged))); 


        /// 
        /// Template Property 
        /// 
        private DataTemplate Template 
        { 
            get {  return _templateCache; }
            set { SetValue(TemplateProperty, value); } 
        }

        // Internal helper so FrameworkElement could see call the template changed virtual
        internal override void OnTemplateChangedInternal(FrameworkTemplate oldTemplate, FrameworkTemplate newTemplate) 
        {
            OnTemplateChanged((DataTemplate)oldTemplate, (DataTemplate)newTemplate); 
        } 

        // Property invalidation callback invoked when TemplateProperty is invalidated 
        private static void OnTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ContentPresenter c = (ContentPresenter) d;
            StyleHelper.UpdateTemplateCache(c, (FrameworkTemplate) e.OldValue, (FrameworkTemplate) e.NewValue, TemplateProperty); 
        }
 
        ///  
        ///     Template has changed
        ///  
        /// 
        ///     When a Template changes, the VisualTree is removed. The new Template's
        ///     VisualTree will be created when ApplyTemplate is called
        ///  
        /// The old Template
        /// The new Template 
        protected virtual void OnTemplateChanged(DataTemplate oldTemplate, DataTemplate newTemplate) 
        {
        } 


        //-----------------------------------------------------
        // 
        //  Private methods
        // 
        //------------------------------------------------------ 

        private void EnsureTemplate() 
        {
            DataTemplate oldTemplate = Template;
            DataTemplate newTemplate = null;
 
            for (_templateIsCurrent = false; !_templateIsCurrent; )
            { 
                // normally this loop will execute exactly once.  The only exception 
                // is when setting the DataContext causes the ContentTemplate or
                // ContentTemplateSelector to change, presumably because they are 
                // themselves data-bound (see bug 128119).  In that case, we need
                // to call ChooseTemplate again, to pick up the new template.
                // We detect this case because _templateIsCurrent is reset to false
                // in OnContentTemplate[Selector]Changed, causing a second iteration 
                // of the loop.
                _templateIsCurrent = true; 
                newTemplate = ChooseTemplate(); 

                // if the template is changing, it's important that the code that cleans 
                // up the old template runs while the CP's DataContext is still set to
                // the old Content.  The way to get this effect is:
                //      a. change the template to null
                //      b. change the data context 
                //      c. change the template to the new value
 
                if (oldTemplate != newTemplate) 
                {
                    Template = null; 
                }

                if (newTemplate != UIElementContentTemplate)
                { 
                    // set data context to the content, so that the template can bind to
                    // properties of the content. 
                    this.DataContext = Content; 
                }
                else 
                {
                    // If we're using the content directly, clear the data context.
                    // The content expects to inherit.
                    this.ClearValue(DataContextProperty); 
                }
            } 
 
            Template = newTemplate;
 
            // if the template didn't change, we still need to force the content for the template to be regenerated;
            // so call StyleHelper's DoTemplateInvalidations directly
            if (oldTemplate == newTemplate)
            { 
                StyleHelper.DoTemplateInvalidations(this, oldTemplate);
            } 
        } 

 
        // ContentPresenter often has occasion to display text.  The TextBlock it uses
        // should get the values for various text-related properties (foreground, fonts,
        // decoration, trimming) from the governing ContentControl.  The following
        // two methods accomplish this - first for the case where the TextBlock appears 
        // in a true template, then for the case where the TextBlock is created on
        // demand via BuildVisualTree. 
 
        // Create a FEF for a AccessText, to be used in a default template
        internal static FrameworkElementFactory CreateAccessTextFactory() 
        {
            FrameworkElementFactory text = new FrameworkElementFactory(typeof(AccessText));

            return text; 
        }
 
        // Create a FEF for a TextBlock, to be used in a default template 
        internal static FrameworkElementFactory CreateTextBlockFactory()
        { 
            FrameworkElementFactory text = new FrameworkElementFactory(typeof(TextBlock));

            return text;
        } 

        // Create a TextBlock, to be used in a default "template" (via BuildVisualTree) 
        static TextBlock CreateTextBlock(ContentPresenter container) 
        {
            TextBlock text = new TextBlock(); 

            return text;
        }
 
        //
        //  This property 
        //  1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject 
        //  2. This is a performance optimization
        // 
        internal override int EffectiveValuesInitialSize
        {
            get { return 28; }
        } 

        //------------------------------------------------------ 
        // 
        //  Private nested classes
        // 
        //-----------------------------------------------------

        // Template for displaying UIElements - use the UIElement itself
        private class UseContentTemplate : DataTemplate 
        {
            public UseContentTemplate() 
            { 
                // We need to preserve the treeState cache on a container node
                // even after all its logical children have been added. This is so the 
                // construction of the template visual tree nodes can consume the cache.
                // This member helps us know whether we should retain the cache for
                // special scenarios when the visual tree is being built via BuildVisualTree
                CanBuildVisualTree = true; 
            }
 
            internal override bool BuildVisualTree(FrameworkElement container) 
            {
                UIElement e = ((ContentPresenter)container).Content as UIElement; 
                StyleHelper.AddCustomTemplateRoot( container, e );

                return true;
            } 
        }
 
 
        // template for displaying content when all else fails
        private class DefaultTemplate : DataTemplate 
        {
            public DefaultTemplate()
            {
                // We need to preserve the treeState cache on a container node 
                // even after all its logical children have been added. This is so the
                // construction of the template visual tree nodes can consume the cache. 
                // This member helps us know whether we should retain the cache for 
                // special scenarios when the visual tree is being built via BuildVisualTree
                CanBuildVisualTree = true; 
            }

            //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
            internal override bool BuildVisualTree(FrameworkElement container) 
            {
                bool tracingEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal); 
                if (tracingEnabled) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.GENERICSTRINGGUID), MS.Utility.EventType.StartEvent, "ContentPresenter.BuildVisualTree"); 
                }

                ContentPresenter cp = (ContentPresenter)container;
                Visual result = DefaultExpansion(cp.Content, cp); 

                if (tracingEnabled) 
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.GENERICSTRINGGUID),
                                                         MS.Utility.EventType.EndEvent, 
                                                         String.Format(System.Globalization.CultureInfo.InvariantCulture, "ContentPresenter.BuildVisualTree for CP {0}", container.GetHashCode()));
                }

                return (result != null); 
            }
 
            private UIElement DefaultExpansion(object content, ContentPresenter container) 
            {
                if (content == null) 
                    return null;

                TextBlock textBlock = CreateTextBlock(container);
                textBlock.IsContentPresenterContainer = true; // this is done so that the TextBlock does not steal away the logical child 
                if( container != null )
                { 
                    StyleHelper.AddCustomTemplateRoot( 
                        container,
                        textBlock, 
                        false, // Do not need to check for existing visual parent since we just created it
                        true); // set treeState cache on the Text instance created
                }
 
                DoDefaultExpansion(textBlock, content);
 
                return textBlock; 
            }
 
            private void DoDefaultExpansion(TextBlock textBlock, object content)
            {
                if (content is string)
                { 
                    textBlock.Text = (string)content;
                } 
                else if (content is Inline) 
                {
                    textBlock.Inlines.Add((Inline)content); 
                }
                else if (content is UIElement)
                {
                    textBlock.Inlines.Add(new InlineUIContainer((UIElement)content)); 
                }
                else 
                { 
                    Type t = content.GetType();
                    TypeConverter tc = TypeDescriptor.GetConverter(t); 
                    if (tc != null)
                    {
                        if (tc.CanConvertTo(typeof(UIElement)))
                        { 
                            UIElement e = (UIElement)tc.ConvertTo(content, typeof(UIElement));
                            textBlock.Inlines.Add(new InlineUIContainer(e)); 
                        } 
                        else if (tc.CanConvertTo(typeof(string)))
                        { 
                            textBlock.Text = (string)tc.ConvertTo(content, typeof(string));
                        }
                    }
                    else 
                    {
                        textBlock.Text = content.ToString(); 
                    } 
                }
            } 

        }

        private class DefaultSelector : DataTemplateSelector 
        {
            ///  
            /// Override this method to return an app specific . 
            /// 
            /// The data content 
            /// The container in which the content is to be displayed
            /// a app specific template to apply.
            public override DataTemplate SelectTemplate(object item, DependencyObject container)
            { 
                DataTemplate template = null;
 
                // Lookup template for typeof(Content) in resource dictionaries. 
                if (item != null)
                { 
                    template = (DataTemplate)FrameworkElement.FindTemplateResourceInternal(container, item, typeof(DataTemplate));
                }

                // default templates for well known types: 
                if (template == null)
                { 
                    if (item is string) 
                    {
                        ContentPresenter cp = container as ContentPresenter; 
                        if (cp != null && cp.RecognizesAccessKey && (item as string).IndexOf(AccessText.AccessKeyMarker) > -1)
                            template = AccessTextContentTemplate;
                        else
                            template = StringContentTemplate; 
                    }
                    else if (item is UIElement) 
                        template = UIElementContentTemplate; 
                    else if (XmlHelper.IsXmlNode(item))
                        template = XmlNodeContentTemplate; 
                    else
                        template = DefaultContentTemplate;
                }
 
                return template;
            } 
        } 

        //------------------------------------------------------ 
        //
        //  Private Fields
        //
        //----------------------------------------------------- 

        private DataTemplate _templateCache; 
 
        private bool _templateIsCurrent;
        private bool _contentIsItem; 

        private static DataTemplate s_AccessTextTemplate;
        private static DataTemplate s_StringTemplate;
        private static DataTemplate s_XmlNodeTemplate; 
        private static DataTemplate s_UIElementTemplate;
        private static DataTemplate s_DefaultTemplate; 
        private static DefaultSelector s_DefaultTemplateSelector; 
    }
} 


// 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