HeaderedItemsControl.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 / Controls / HeaderedItemsControl.cs / 3 / HeaderedItemsControl.cs

                            using System; 
using System.Collections;
using System.ComponentModel;
using System.Windows.Threading;
 
using System.Windows.Data;
using System.Windows.Media; 
 
using MS.Utility;
using MS.Internal; 
using MS.Internal.Controls;
using MS.Internal.KnownBoxes;
using MS.Internal.Data;
using MS.Internal.PresentationFramework; 

namespace System.Windows.Controls 
{ 
    /// 
    ///     The base class for all controls that contain multiple items and have a header. 
    /// 
    /// 
    ///     HeaderedItemsControl adds Header, HeaderTemplate, and Part features to an ItemsControl.
    ///  
    [DefaultProperty("Header")]
    [Localizability(LocalizationCategory.Menu)] 
    public class HeaderedItemsControl : ItemsControl 
    {
        #region Constructors 

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

        #endregion 

        #region Properties 
 
        /// 
        ///     The DependencyProperty for the Header property. 
        ///     Flags:              None
        ///     Default Value:      null
        /// 
        [CommonDependencyProperty] 
        public static readonly DependencyProperty HeaderProperty =
                HeaderedContentControl.HeaderProperty.AddOwner( 
                        typeof(HeaderedItemsControl), 
                        new FrameworkPropertyMetadata(
                                (object) null, 
                                new PropertyChangedCallback(OnHeaderChanged)));


        ///  
        ///     Header is the data used to for the header of each item in the control.
        ///  
        [Bindable(true), CustomCategory("Content")] 
        public object Header
        { 
            get { return GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }
 
        /// 
        ///     Called when HeaderProperty is invalidated on "d." 
        ///  
        private static void OnHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            HeaderedItemsControl ctrl = (HeaderedItemsControl) d;

            ctrl.SetValue(HasHeaderPropertyKey, (e.NewValue != null) ? BooleanBoxes.TrueBox : BooleanBoxes.FalseBox);
            ctrl.OnHeaderChanged(e.OldValue, e.NewValue); 
        }
 
        ///  
        ///     This method is invoked when the Header property changes.
        ///  
        /// The old value of the Header property.
        /// The new value of the Header property.
        protected virtual void OnHeaderChanged(object oldHeader, object newHeader)
        { 
            // if Header should not be treated as a logical child, there's
            // nothing to do 
            if (!IsHeaderLogical()) 
                return;
 
            RemoveLogicalChild(oldHeader);
            AddLogicalChild(newHeader);
        }
 
        /// 
        ///     The key needed set a read-only property. 
        ///  
        private static readonly DependencyPropertyKey HasHeaderPropertyKey =
                HeaderedContentControl.HasHeaderPropertyKey; 

        /// 
        ///     The DependencyProperty for the HasHeader property.
        ///     Flags:              None 
        ///     Other:              Read-Only
        ///     Default Value:      false 
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty HasHeaderProperty = HeaderedContentControl.HasHeaderProperty.AddOwner(typeof(HeaderedItemsControl)); 

        /// 
        ///     True if Header is non-null, false otherwise.
        ///  
        [Bindable(false), Browsable(false)]
        public bool HasHeader 
        { 
            get { return (bool) GetValue(HasHeaderProperty); }
        } 

        /// 
        ///     The DependencyProperty for the HeaderTemplate property.
        ///     Flags:              Can be used in style rules 
        ///     Default Value:      null
        ///  
        [CommonDependencyProperty] 
        public static readonly DependencyProperty HeaderTemplateProperty =
                HeaderedContentControl.HeaderTemplateProperty.AddOwner( 
                        typeof(HeaderedItemsControl),
                        new FrameworkPropertyMetadata(
                                (DataTemplate) null,
                                new PropertyChangedCallback(OnHeaderTemplateChanged))); 

        ///  
        ///     HeaderTemplate is the template used to display the header of each item. 
        /// 
        [Bindable(true), CustomCategory("Content")] 
        public DataTemplate HeaderTemplate
        {
            get { return (DataTemplate) GetValue(HeaderTemplateProperty); }
            set { SetValue(HeaderTemplateProperty, value); } 
        }
 
        ///  
        ///     Called when HeaderTemplateProperty is invalidated on "d."
        ///  
        private static void OnHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            HeaderedItemsControl ctrl = (HeaderedItemsControl) d;
            ctrl.OnHeaderTemplateChanged((DataTemplate) e.OldValue, (DataTemplate) e.NewValue); 
        }
 
        ///  
        ///     This method is invoked when the HeaderTemplate property changes.
        ///  
        /// The old value of the HeaderTemplate property.
        /// The new value of the HeaderTemplate property.
        protected virtual void OnHeaderTemplateChanged(DataTemplate oldHeaderTemplate, DataTemplate newHeaderTemplate)
        { 
            Helper.CheckTemplateAndTemplateSelector("Header", HeaderTemplateProperty, HeaderTemplateSelectorProperty, this);
        } 
 

        ///  
        ///     The DependencyProperty for the HeaderTemplateSelector property.
        ///     Flags:              none
        ///     Default Value:      null
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty HeaderTemplateSelectorProperty = 
                HeaderedContentControl.HeaderTemplateSelectorProperty.AddOwner( 
                        typeof(HeaderedItemsControl),
                        new FrameworkPropertyMetadata( 
                                (DataTemplateSelector) null,
                                new PropertyChangedCallback(OnHeaderTemplateSelectorChanged)));

        ///  
        ///     HeaderTemplateSelector allows the application writer to provide custom logic
        ///     for choosing the template used to display the header of each item. 
        ///  
        /// 
        ///     This property is ignored if  is set. 
        /// 
        [Bindable(true), CustomCategory("Content")]
        public DataTemplateSelector HeaderTemplateSelector
        { 
            get { return (DataTemplateSelector) GetValue(HeaderTemplateSelectorProperty); }
            set { SetValue(HeaderTemplateSelectorProperty, value); } 
        } 

        ///  
        ///     Called when HeaderTemplateSelectorProperty is invalidated on "d."
        /// 
        private static void OnHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            HeaderedItemsControl ctrl = (HeaderedItemsControl) d;
            ctrl.OnHeaderTemplateSelectorChanged((DataTemplateSelector) e.OldValue, (DataTemplateSelector) e.NewValue); 
        } 

        ///  
        ///     This method is invoked when the HeaderTemplateSelector property changes.
        /// 
        /// The old value of the HeaderTemplateSelector property.
        /// The new value of the HeaderTemplateSelector property. 
        protected virtual void OnHeaderTemplateSelectorChanged(DataTemplateSelector oldHeaderTemplateSelector, DataTemplateSelector newHeaderTemplateSelector)
        { 
            Helper.CheckTemplateAndTemplateSelector("Header", HeaderTemplateProperty, HeaderTemplateSelectorProperty, this); 
        }
 
        /// 
        ///     The DependencyProperty for the HeaderStringFormat property.
        ///     Flags:              None
        ///     Default Value:      null 
        /// 
        [CommonDependencyProperty] 
        public static readonly DependencyProperty HeaderStringFormatProperty = 
                DependencyProperty.Register(
                        "HeaderStringFormat", 
                        typeof(String),
                        typeof(HeaderedItemsControl),
                        new FrameworkPropertyMetadata(
                                (String) null, 
                              new PropertyChangedCallback(OnHeaderStringFormatChanged)));
 
 
        /// 
        ///     HeaderStringFormat is the format used to display the header content as a string. 
        ///     This arises only when no template is available.
        /// 
        [Bindable(true), CustomCategory("Content")]
        public String HeaderStringFormat 
        {
            get { return (String) GetValue(HeaderStringFormatProperty); } 
            set { SetValue(HeaderStringFormatProperty, value); } 
        }
 
        /// 
        ///     Called when HeaderStringFormatProperty is invalidated on "d."
        /// 
        private static void OnHeaderStringFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            HeaderedItemsControl ctrl = (HeaderedItemsControl)d; 
            ctrl.OnHeaderStringFormatChanged((String) e.OldValue, (String) e.NewValue); 
        }
 
        /// 
        ///     This method is invoked when the HeaderStringFormat property changes.
        /// 
        /// The old value of the HeaderStringFormat property. 
        /// The new value of the HeaderStringFormat property.
        protected virtual void OnHeaderStringFormatChanged(String oldHeaderStringFormat, String newHeaderStringFormat) 
        { 
        }
 
        #endregion

        #region Internal Methods
 
        /// 
        /// Prepare to display the item. 
        ///  
        internal void PrepareHeaderedItemsControl(object item, ItemsControl parentItemsControl)
        { 
            bool headerIsNotLogical = item != this;
            // don't treat Header as a logical child
            WriteControlFlag(ControlBoolFlags.HeaderIsNotLogical, headerIsNotLogical);
 
            // copy styles from parent ItemsControl
            PrepareItemsControl(item, parentItemsControl); 
 
            if (headerIsNotLogical)
            { 
                if (HeaderIsItem || !HasNonDefaultValue(HeaderProperty))
                {
                    Header = item;
                    HeaderIsItem = true; 
                }
 
                DataTemplate itemTemplate = parentItemsControl.ItemTemplate; 
                DataTemplateSelector itemTemplateSelector = parentItemsControl.ItemTemplateSelector;
                string itemStringFormat = parentItemsControl.ItemStringFormat; 

                if (itemTemplate != null)
                {
                    SetValue(HeaderTemplateProperty, itemTemplate); 
                }
                if (itemTemplateSelector != null) 
                { 
                    SetValue(HeaderTemplateSelectorProperty, itemTemplateSelector);
                } 
                if (itemStringFormat != null &&
                    Helper.HasDefaultValue(HeaderStringFormatProperty, this, this, null))
                {
                    SetValue(HeaderStringFormatProperty, itemStringFormat); 
                }
 
                PrepareHierarchy(item, parentItemsControl); 
            }
        } 

        /// 
        ///     Gives a string representation of this object.
        ///  
        /// 
        internal override string GetPlainText() 
        { 
            return ContentControl.ContentObjectToString(Header);
        } 

        #endregion

        #region Method Overrides 

        ///  
        ///     Gives a string representation of this object. 
        /// 
        public override string ToString() 
        {
            string typeText = this.GetType().ToString();
            string headerText = String.Empty;
            int itemCount = 0; 
            bool valuesDefined = false;
 
            // Accessing Header's content may be thread sensitive 
            if (CheckAccess())
            { 
                headerText = ContentControl.ContentObjectToString(Header);
                // HasItems may be wrong when underlying collection does not notify,
                // but this function should try to return what's consistent with ItemsControl state.
                itemCount = HasItems ? Items.Count : 0; 
                valuesDefined = true;
            } 
            else 
            {
                //Not on dispatcher, try posting to the dispatcher with 20ms timeout 
                Dispatcher.Invoke(DispatcherPriority.Send, new TimeSpan(0, 0, 0, 0, 20), new DispatcherOperationCallback(delegate(object o)
                {
                    headerText = ContentControl.ContentObjectToString(Header);
                    // HasItems may be wrong when underlying collection does not notify, 
                    // but this function should try to return what's consistent with ItemsControl state.
                    itemCount = HasItems ? Items.Count : 0; 
                    valuesDefined = true; 
                    return null;
                }), null); 
            }

            // If header and items count are defined
            if (valuesDefined) 
            {
                return SR.Get(SRID.ToStringFormatString_HeaderedItemsControl, typeText, headerText, itemCount); 
            } 

            // Not able to access the dispatcher 
            return typeText;
        }

        #endregion 

        #region LogicalTree 
 
        /// 
        ///     Returns enumerator to logical children 
        /// 
        protected internal override IEnumerator LogicalChildren
        {
            get 
            {
                object header = Header; 
 
                if (ReadControlFlag(ControlBoolFlags.HeaderIsNotLogical) || header == null)
                { 
                    return base.LogicalChildren;
                }

                return new HeaderedItemsModelTreeEnumerator(this, base.LogicalChildren, header); 
            }
        } 
 
        #endregion
 
        #region Private methods

        // As a convenience for hierarchical data, get the header template and
        // if it's a HierarchicalDataTemplate, set the ItemsSource, ItemTemplate, 
        // ItemTemplateSelector, and ItemStringFormat properties from the template.
        void PrepareHierarchy(object item, ItemsControl parentItemsControl) 
        { 
            // get the effective header template
            DataTemplate headerTemplate = HeaderTemplate; 

            if (headerTemplate == null)
            {
                DataTemplateSelector selector = HeaderTemplateSelector; 
                if (selector != null)
                { 
                    headerTemplate = selector.SelectTemplate(item, this); 
                }
            } 

            if (headerTemplate == null)
            {
                headerTemplate = (DataTemplate)FindTemplateResourceInternal(this, item, typeof(DataTemplate)); 
                if (headerTemplate != null)
                { 
                    // if we discovered the template by a type-based resource lookup, 
                    // set it locally.  This means the ContentPresenter that displays
                    // the header won't have to do another lookup, but also means 
                    // that if the CP's lookup would have produced a different result,
                    // we won't use it.
                    ClearValue(HeaderTemplateProperty); // remove binding
                    HeaderTemplate = headerTemplate; 
                }
            } 
 
            // if the effective template is a HierarchicalDataTemplate, forward
            // the special properties 
            HierarchicalDataTemplate hTemplate = headerTemplate as HierarchicalDataTemplate;
            if (hTemplate != null)
            {
                bool templateMatches = (ItemTemplate == parentItemsControl.ItemTemplate); 
                bool containerStyleMatches = (ItemContainerStyle == parentItemsControl.ItemContainerStyle);
 
                if (hTemplate.ItemsSource != null && !HasNonDefaultValue(ItemsSourceProperty)) 
                {
                    SetBinding(ItemsSourceProperty, hTemplate.ItemsSource); 
                }

                if (hTemplate.IsItemStringFormatSet && ItemStringFormat == parentItemsControl.ItemStringFormat)
                { 
                    // if the HDT defines a string format, turn off the
                    // forwarding of ItemTemplate[Selector] (which would get in the way). 
                    ClearValue(ItemTemplateProperty); 
                    ClearValue(ItemTemplateSelectorProperty);
 
                    // forward the HDT's string format
                    ClearValue(ItemStringFormatProperty);
                    bool setItemStringFormat = (hTemplate.ItemStringFormat != null);
                    if (setItemStringFormat) 
                    {
                        ItemStringFormat = hTemplate.ItemStringFormat; 
                    } 
                }
 
                if (hTemplate.IsItemTemplateSelectorSet && ItemTemplateSelector == parentItemsControl.ItemTemplateSelector)
                {
                    // if the HDT defines a template selector, turn off the
                    // forwarding of ItemTemplate (which would get in the way). 
                    ClearValue(ItemTemplateProperty);
 
                    // forward the HDT's template selector 
                    ClearValue(ItemTemplateSelectorProperty);
                    bool setItemTemplateSelector = (hTemplate.ItemTemplateSelector != null); 
                    if (setItemTemplateSelector)
                    {
                        ItemTemplateSelector = hTemplate.ItemTemplateSelector;
                    } 
                }
 
                if (hTemplate.IsItemTemplateSet && templateMatches) 
                {
                    // forward the HDT's template 
                    ClearValue(ItemTemplateProperty);
                    bool setItemTemplate = (hTemplate.ItemTemplate != null);
                    if (setItemTemplate)
                    { 
                        ItemTemplate = hTemplate.ItemTemplate;
                    } 
                } 

                if (hTemplate.IsItemContainerStyleSelectorSet && ItemContainerStyleSelector == parentItemsControl.ItemContainerStyleSelector) 
                {
                    // if the HDT defines a container-style selector, turn off the
                    // forwarding of ItemContainerStyle (which would get in the way).
                    ClearValue(ItemContainerStyleProperty); 

                    // forward the HDT's container-style selector 
                    ClearValue(ItemContainerStyleSelectorProperty); 
                    bool setItemContainerStyleSelector = (hTemplate.ItemContainerStyleSelector != null);
                    if (setItemContainerStyleSelector) 
                    {
                        ItemContainerStyleSelector = hTemplate.ItemContainerStyleSelector;
                    }
                } 

                if (hTemplate.IsItemContainerStyleSet && containerStyleMatches) 
                { 
                    // forward the HDT's container style
                    ClearValue(ItemContainerStyleProperty); 
                    bool setItemContainerStyle = (hTemplate.ItemContainerStyle != null);
                    if (setItemContainerStyle)
                    {
                        ItemContainerStyle = hTemplate.ItemContainerStyle; 
                    }
                } 
 
                if (hTemplate.IsAlternationCountSet && AlternationCount == parentItemsControl.AlternationCount)
                { 
                    // forward the HDT's alternation count
                    ClearValue(AlternationCountProperty);
                    bool setAlternationCount = true;
                    if (setAlternationCount) 
                    {
                        AlternationCount = hTemplate.AlternationCount; 
                    } 
                }
 
                if (hTemplate.IsItemBindingGroupSet && ItemBindingGroup == parentItemsControl.ItemBindingGroup)
                {
                    // forward the HDT's ItemBindingGroup
                    ClearValue(ItemBindingGroupProperty); 
                    bool setItemBindingGroup = (hTemplate.ItemBindingGroup != null);
                    if (setItemBindingGroup) 
                    { 
                        ItemBindingGroup = hTemplate.ItemBindingGroup;
                    } 
                }
            }
        }
 
        // return true if the dp is bound via the given Binding
        bool IsBound(DependencyProperty dp, Binding binding) 
        { 
            BindingExpressionBase bindExpr = BindingOperations.GetBindingExpression(this, dp);
            return (bindExpr != null && bindExpr.ParentBindingBase == binding); 
        }

        // return true if the Header should be a logical child
        bool IsHeaderLogical() 
        {
            // use cached result, if available 
            if (ReadControlFlag(ControlBoolFlags.HeaderIsNotLogical)) 
                return false;
 
            // if Header property is data-bound, it should not be logical
            if (BindingOperations.IsDataBound(this, HeaderProperty))
            {
                WriteControlFlag(ControlBoolFlags.HeaderIsNotLogical, true); 
                return false;
            } 
 
            // otherwise, Header is logical
            return true; 
        }

        // return true if the Header is a data item
        bool HeaderIsItem 
        {
            get { return ReadControlFlag(ControlBoolFlags.HeaderIsItem); } 
            set { WriteControlFlag(ControlBoolFlags.HeaderIsItem, value); } 
        }
 

        #endregion Private methods

    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Collections;
using System.ComponentModel;
using System.Windows.Threading;
 
using System.Windows.Data;
using System.Windows.Media; 
 
using MS.Utility;
using MS.Internal; 
using MS.Internal.Controls;
using MS.Internal.KnownBoxes;
using MS.Internal.Data;
using MS.Internal.PresentationFramework; 

namespace System.Windows.Controls 
{ 
    /// 
    ///     The base class for all controls that contain multiple items and have a header. 
    /// 
    /// 
    ///     HeaderedItemsControl adds Header, HeaderTemplate, and Part features to an ItemsControl.
    ///  
    [DefaultProperty("Header")]
    [Localizability(LocalizationCategory.Menu)] 
    public class HeaderedItemsControl : ItemsControl 
    {
        #region Constructors 

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

        #endregion 

        #region Properties 
 
        /// 
        ///     The DependencyProperty for the Header property. 
        ///     Flags:              None
        ///     Default Value:      null
        /// 
        [CommonDependencyProperty] 
        public static readonly DependencyProperty HeaderProperty =
                HeaderedContentControl.HeaderProperty.AddOwner( 
                        typeof(HeaderedItemsControl), 
                        new FrameworkPropertyMetadata(
                                (object) null, 
                                new PropertyChangedCallback(OnHeaderChanged)));


        ///  
        ///     Header is the data used to for the header of each item in the control.
        ///  
        [Bindable(true), CustomCategory("Content")] 
        public object Header
        { 
            get { return GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }
 
        /// 
        ///     Called when HeaderProperty is invalidated on "d." 
        ///  
        private static void OnHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            HeaderedItemsControl ctrl = (HeaderedItemsControl) d;

            ctrl.SetValue(HasHeaderPropertyKey, (e.NewValue != null) ? BooleanBoxes.TrueBox : BooleanBoxes.FalseBox);
            ctrl.OnHeaderChanged(e.OldValue, e.NewValue); 
        }
 
        ///  
        ///     This method is invoked when the Header property changes.
        ///  
        /// The old value of the Header property.
        /// The new value of the Header property.
        protected virtual void OnHeaderChanged(object oldHeader, object newHeader)
        { 
            // if Header should not be treated as a logical child, there's
            // nothing to do 
            if (!IsHeaderLogical()) 
                return;
 
            RemoveLogicalChild(oldHeader);
            AddLogicalChild(newHeader);
        }
 
        /// 
        ///     The key needed set a read-only property. 
        ///  
        private static readonly DependencyPropertyKey HasHeaderPropertyKey =
                HeaderedContentControl.HasHeaderPropertyKey; 

        /// 
        ///     The DependencyProperty for the HasHeader property.
        ///     Flags:              None 
        ///     Other:              Read-Only
        ///     Default Value:      false 
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty HasHeaderProperty = HeaderedContentControl.HasHeaderProperty.AddOwner(typeof(HeaderedItemsControl)); 

        /// 
        ///     True if Header is non-null, false otherwise.
        ///  
        [Bindable(false), Browsable(false)]
        public bool HasHeader 
        { 
            get { return (bool) GetValue(HasHeaderProperty); }
        } 

        /// 
        ///     The DependencyProperty for the HeaderTemplate property.
        ///     Flags:              Can be used in style rules 
        ///     Default Value:      null
        ///  
        [CommonDependencyProperty] 
        public static readonly DependencyProperty HeaderTemplateProperty =
                HeaderedContentControl.HeaderTemplateProperty.AddOwner( 
                        typeof(HeaderedItemsControl),
                        new FrameworkPropertyMetadata(
                                (DataTemplate) null,
                                new PropertyChangedCallback(OnHeaderTemplateChanged))); 

        ///  
        ///     HeaderTemplate is the template used to display the header of each item. 
        /// 
        [Bindable(true), CustomCategory("Content")] 
        public DataTemplate HeaderTemplate
        {
            get { return (DataTemplate) GetValue(HeaderTemplateProperty); }
            set { SetValue(HeaderTemplateProperty, value); } 
        }
 
        ///  
        ///     Called when HeaderTemplateProperty is invalidated on "d."
        ///  
        private static void OnHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            HeaderedItemsControl ctrl = (HeaderedItemsControl) d;
            ctrl.OnHeaderTemplateChanged((DataTemplate) e.OldValue, (DataTemplate) e.NewValue); 
        }
 
        ///  
        ///     This method is invoked when the HeaderTemplate property changes.
        ///  
        /// The old value of the HeaderTemplate property.
        /// The new value of the HeaderTemplate property.
        protected virtual void OnHeaderTemplateChanged(DataTemplate oldHeaderTemplate, DataTemplate newHeaderTemplate)
        { 
            Helper.CheckTemplateAndTemplateSelector("Header", HeaderTemplateProperty, HeaderTemplateSelectorProperty, this);
        } 
 

        ///  
        ///     The DependencyProperty for the HeaderTemplateSelector property.
        ///     Flags:              none
        ///     Default Value:      null
        ///  
        [CommonDependencyProperty]
        public static readonly DependencyProperty HeaderTemplateSelectorProperty = 
                HeaderedContentControl.HeaderTemplateSelectorProperty.AddOwner( 
                        typeof(HeaderedItemsControl),
                        new FrameworkPropertyMetadata( 
                                (DataTemplateSelector) null,
                                new PropertyChangedCallback(OnHeaderTemplateSelectorChanged)));

        ///  
        ///     HeaderTemplateSelector allows the application writer to provide custom logic
        ///     for choosing the template used to display the header of each item. 
        ///  
        /// 
        ///     This property is ignored if  is set. 
        /// 
        [Bindable(true), CustomCategory("Content")]
        public DataTemplateSelector HeaderTemplateSelector
        { 
            get { return (DataTemplateSelector) GetValue(HeaderTemplateSelectorProperty); }
            set { SetValue(HeaderTemplateSelectorProperty, value); } 
        } 

        ///  
        ///     Called when HeaderTemplateSelectorProperty is invalidated on "d."
        /// 
        private static void OnHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            HeaderedItemsControl ctrl = (HeaderedItemsControl) d;
            ctrl.OnHeaderTemplateSelectorChanged((DataTemplateSelector) e.OldValue, (DataTemplateSelector) e.NewValue); 
        } 

        ///  
        ///     This method is invoked when the HeaderTemplateSelector property changes.
        /// 
        /// The old value of the HeaderTemplateSelector property.
        /// The new value of the HeaderTemplateSelector property. 
        protected virtual void OnHeaderTemplateSelectorChanged(DataTemplateSelector oldHeaderTemplateSelector, DataTemplateSelector newHeaderTemplateSelector)
        { 
            Helper.CheckTemplateAndTemplateSelector("Header", HeaderTemplateProperty, HeaderTemplateSelectorProperty, this); 
        }
 
        /// 
        ///     The DependencyProperty for the HeaderStringFormat property.
        ///     Flags:              None
        ///     Default Value:      null 
        /// 
        [CommonDependencyProperty] 
        public static readonly DependencyProperty HeaderStringFormatProperty = 
                DependencyProperty.Register(
                        "HeaderStringFormat", 
                        typeof(String),
                        typeof(HeaderedItemsControl),
                        new FrameworkPropertyMetadata(
                                (String) null, 
                              new PropertyChangedCallback(OnHeaderStringFormatChanged)));
 
 
        /// 
        ///     HeaderStringFormat is the format used to display the header content as a string. 
        ///     This arises only when no template is available.
        /// 
        [Bindable(true), CustomCategory("Content")]
        public String HeaderStringFormat 
        {
            get { return (String) GetValue(HeaderStringFormatProperty); } 
            set { SetValue(HeaderStringFormatProperty, value); } 
        }
 
        /// 
        ///     Called when HeaderStringFormatProperty is invalidated on "d."
        /// 
        private static void OnHeaderStringFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            HeaderedItemsControl ctrl = (HeaderedItemsControl)d; 
            ctrl.OnHeaderStringFormatChanged((String) e.OldValue, (String) e.NewValue); 
        }
 
        /// 
        ///     This method is invoked when the HeaderStringFormat property changes.
        /// 
        /// The old value of the HeaderStringFormat property. 
        /// The new value of the HeaderStringFormat property.
        protected virtual void OnHeaderStringFormatChanged(String oldHeaderStringFormat, String newHeaderStringFormat) 
        { 
        }
 
        #endregion

        #region Internal Methods
 
        /// 
        /// Prepare to display the item. 
        ///  
        internal void PrepareHeaderedItemsControl(object item, ItemsControl parentItemsControl)
        { 
            bool headerIsNotLogical = item != this;
            // don't treat Header as a logical child
            WriteControlFlag(ControlBoolFlags.HeaderIsNotLogical, headerIsNotLogical);
 
            // copy styles from parent ItemsControl
            PrepareItemsControl(item, parentItemsControl); 
 
            if (headerIsNotLogical)
            { 
                if (HeaderIsItem || !HasNonDefaultValue(HeaderProperty))
                {
                    Header = item;
                    HeaderIsItem = true; 
                }
 
                DataTemplate itemTemplate = parentItemsControl.ItemTemplate; 
                DataTemplateSelector itemTemplateSelector = parentItemsControl.ItemTemplateSelector;
                string itemStringFormat = parentItemsControl.ItemStringFormat; 

                if (itemTemplate != null)
                {
                    SetValue(HeaderTemplateProperty, itemTemplate); 
                }
                if (itemTemplateSelector != null) 
                { 
                    SetValue(HeaderTemplateSelectorProperty, itemTemplateSelector);
                } 
                if (itemStringFormat != null &&
                    Helper.HasDefaultValue(HeaderStringFormatProperty, this, this, null))
                {
                    SetValue(HeaderStringFormatProperty, itemStringFormat); 
                }
 
                PrepareHierarchy(item, parentItemsControl); 
            }
        } 

        /// 
        ///     Gives a string representation of this object.
        ///  
        /// 
        internal override string GetPlainText() 
        { 
            return ContentControl.ContentObjectToString(Header);
        } 

        #endregion

        #region Method Overrides 

        ///  
        ///     Gives a string representation of this object. 
        /// 
        public override string ToString() 
        {
            string typeText = this.GetType().ToString();
            string headerText = String.Empty;
            int itemCount = 0; 
            bool valuesDefined = false;
 
            // Accessing Header's content may be thread sensitive 
            if (CheckAccess())
            { 
                headerText = ContentControl.ContentObjectToString(Header);
                // HasItems may be wrong when underlying collection does not notify,
                // but this function should try to return what's consistent with ItemsControl state.
                itemCount = HasItems ? Items.Count : 0; 
                valuesDefined = true;
            } 
            else 
            {
                //Not on dispatcher, try posting to the dispatcher with 20ms timeout 
                Dispatcher.Invoke(DispatcherPriority.Send, new TimeSpan(0, 0, 0, 0, 20), new DispatcherOperationCallback(delegate(object o)
                {
                    headerText = ContentControl.ContentObjectToString(Header);
                    // HasItems may be wrong when underlying collection does not notify, 
                    // but this function should try to return what's consistent with ItemsControl state.
                    itemCount = HasItems ? Items.Count : 0; 
                    valuesDefined = true; 
                    return null;
                }), null); 
            }

            // If header and items count are defined
            if (valuesDefined) 
            {
                return SR.Get(SRID.ToStringFormatString_HeaderedItemsControl, typeText, headerText, itemCount); 
            } 

            // Not able to access the dispatcher 
            return typeText;
        }

        #endregion 

        #region LogicalTree 
 
        /// 
        ///     Returns enumerator to logical children 
        /// 
        protected internal override IEnumerator LogicalChildren
        {
            get 
            {
                object header = Header; 
 
                if (ReadControlFlag(ControlBoolFlags.HeaderIsNotLogical) || header == null)
                { 
                    return base.LogicalChildren;
                }

                return new HeaderedItemsModelTreeEnumerator(this, base.LogicalChildren, header); 
            }
        } 
 
        #endregion
 
        #region Private methods

        // As a convenience for hierarchical data, get the header template and
        // if it's a HierarchicalDataTemplate, set the ItemsSource, ItemTemplate, 
        // ItemTemplateSelector, and ItemStringFormat properties from the template.
        void PrepareHierarchy(object item, ItemsControl parentItemsControl) 
        { 
            // get the effective header template
            DataTemplate headerTemplate = HeaderTemplate; 

            if (headerTemplate == null)
            {
                DataTemplateSelector selector = HeaderTemplateSelector; 
                if (selector != null)
                { 
                    headerTemplate = selector.SelectTemplate(item, this); 
                }
            } 

            if (headerTemplate == null)
            {
                headerTemplate = (DataTemplate)FindTemplateResourceInternal(this, item, typeof(DataTemplate)); 
                if (headerTemplate != null)
                { 
                    // if we discovered the template by a type-based resource lookup, 
                    // set it locally.  This means the ContentPresenter that displays
                    // the header won't have to do another lookup, but also means 
                    // that if the CP's lookup would have produced a different result,
                    // we won't use it.
                    ClearValue(HeaderTemplateProperty); // remove binding
                    HeaderTemplate = headerTemplate; 
                }
            } 
 
            // if the effective template is a HierarchicalDataTemplate, forward
            // the special properties 
            HierarchicalDataTemplate hTemplate = headerTemplate as HierarchicalDataTemplate;
            if (hTemplate != null)
            {
                bool templateMatches = (ItemTemplate == parentItemsControl.ItemTemplate); 
                bool containerStyleMatches = (ItemContainerStyle == parentItemsControl.ItemContainerStyle);
 
                if (hTemplate.ItemsSource != null && !HasNonDefaultValue(ItemsSourceProperty)) 
                {
                    SetBinding(ItemsSourceProperty, hTemplate.ItemsSource); 
                }

                if (hTemplate.IsItemStringFormatSet && ItemStringFormat == parentItemsControl.ItemStringFormat)
                { 
                    // if the HDT defines a string format, turn off the
                    // forwarding of ItemTemplate[Selector] (which would get in the way). 
                    ClearValue(ItemTemplateProperty); 
                    ClearValue(ItemTemplateSelectorProperty);
 
                    // forward the HDT's string format
                    ClearValue(ItemStringFormatProperty);
                    bool setItemStringFormat = (hTemplate.ItemStringFormat != null);
                    if (setItemStringFormat) 
                    {
                        ItemStringFormat = hTemplate.ItemStringFormat; 
                    } 
                }
 
                if (hTemplate.IsItemTemplateSelectorSet && ItemTemplateSelector == parentItemsControl.ItemTemplateSelector)
                {
                    // if the HDT defines a template selector, turn off the
                    // forwarding of ItemTemplate (which would get in the way). 
                    ClearValue(ItemTemplateProperty);
 
                    // forward the HDT's template selector 
                    ClearValue(ItemTemplateSelectorProperty);
                    bool setItemTemplateSelector = (hTemplate.ItemTemplateSelector != null); 
                    if (setItemTemplateSelector)
                    {
                        ItemTemplateSelector = hTemplate.ItemTemplateSelector;
                    } 
                }
 
                if (hTemplate.IsItemTemplateSet && templateMatches) 
                {
                    // forward the HDT's template 
                    ClearValue(ItemTemplateProperty);
                    bool setItemTemplate = (hTemplate.ItemTemplate != null);
                    if (setItemTemplate)
                    { 
                        ItemTemplate = hTemplate.ItemTemplate;
                    } 
                } 

                if (hTemplate.IsItemContainerStyleSelectorSet && ItemContainerStyleSelector == parentItemsControl.ItemContainerStyleSelector) 
                {
                    // if the HDT defines a container-style selector, turn off the
                    // forwarding of ItemContainerStyle (which would get in the way).
                    ClearValue(ItemContainerStyleProperty); 

                    // forward the HDT's container-style selector 
                    ClearValue(ItemContainerStyleSelectorProperty); 
                    bool setItemContainerStyleSelector = (hTemplate.ItemContainerStyleSelector != null);
                    if (setItemContainerStyleSelector) 
                    {
                        ItemContainerStyleSelector = hTemplate.ItemContainerStyleSelector;
                    }
                } 

                if (hTemplate.IsItemContainerStyleSet && containerStyleMatches) 
                { 
                    // forward the HDT's container style
                    ClearValue(ItemContainerStyleProperty); 
                    bool setItemContainerStyle = (hTemplate.ItemContainerStyle != null);
                    if (setItemContainerStyle)
                    {
                        ItemContainerStyle = hTemplate.ItemContainerStyle; 
                    }
                } 
 
                if (hTemplate.IsAlternationCountSet && AlternationCount == parentItemsControl.AlternationCount)
                { 
                    // forward the HDT's alternation count
                    ClearValue(AlternationCountProperty);
                    bool setAlternationCount = true;
                    if (setAlternationCount) 
                    {
                        AlternationCount = hTemplate.AlternationCount; 
                    } 
                }
 
                if (hTemplate.IsItemBindingGroupSet && ItemBindingGroup == parentItemsControl.ItemBindingGroup)
                {
                    // forward the HDT's ItemBindingGroup
                    ClearValue(ItemBindingGroupProperty); 
                    bool setItemBindingGroup = (hTemplate.ItemBindingGroup != null);
                    if (setItemBindingGroup) 
                    { 
                        ItemBindingGroup = hTemplate.ItemBindingGroup;
                    } 
                }
            }
        }
 
        // return true if the dp is bound via the given Binding
        bool IsBound(DependencyProperty dp, Binding binding) 
        { 
            BindingExpressionBase bindExpr = BindingOperations.GetBindingExpression(this, dp);
            return (bindExpr != null && bindExpr.ParentBindingBase == binding); 
        }

        // return true if the Header should be a logical child
        bool IsHeaderLogical() 
        {
            // use cached result, if available 
            if (ReadControlFlag(ControlBoolFlags.HeaderIsNotLogical)) 
                return false;
 
            // if Header property is data-bound, it should not be logical
            if (BindingOperations.IsDataBound(this, HeaderProperty))
            {
                WriteControlFlag(ControlBoolFlags.HeaderIsNotLogical, true); 
                return false;
            } 
 
            // otherwise, Header is logical
            return true; 
        }

        // return true if the Header is a data item
        bool HeaderIsItem 
        {
            get { return ReadControlFlag(ControlBoolFlags.HeaderIsItem); } 
            set { WriteControlFlag(ControlBoolFlags.HeaderIsItem, value); } 
        }
 

        #endregion Private methods

    } 
}

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