List.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 / Documents / List.cs / 1 / List.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
// Description: Implements a List element, a container for ListElementItems: ' 
//              block elements designed to be formatted with markers such as
//              bullets and numbering. 
// 
// History:
//  06/06/2003 : [....] - created. 
//  10/28/2004 : [....] - ContentElements refactoring.
//
//---------------------------------------------------------------------------
 
using System.ComponentModel;
using System.Windows.Markup; 
using MS.Internal; 
using MS.Internal.PtsHost.UnsafeNativeMethods;      // PTS restrictions
 
namespace System.Windows.Documents
{
    /// 
    /// Implements a List element, a container for ListItems: block 
    /// elements designed to be formatted with markers such as bullets and
    /// numbering. 
    ///  
    [ContentProperty("ListItems")]
    public class List : Block 
    {
        //-------------------------------------------------------------------
        //
        //  Constructors 
        //
        //------------------------------------------------------------------- 
 
        #region Constructors
 
        /// 
        /// List static constructor. Registers metadata for its properties.
        /// 
        static List() 
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(List), new FrameworkPropertyMetadata(typeof(List))); 
        } 

        ///  
        /// Initializes a new instance of a List class.
        /// 
        public List()
            : base() 
        {
        } 
 
        /// 
        /// Initializes a new instance of a List class specifying its first ListItem child. 
        /// 
        /// 
        /// ListItem to be inserted as a first child of this List.
        ///  
        public List(ListItem listItem)
            : base() 
        { 
            if (listItem == null)
            { 
                throw new ArgumentNullException("listItem");
            }
            this.ListItems.Add(listItem);
        } 

        #endregion Constructors 
 
        //--------------------------------------------------------------------
        // 
        //  Public Properties
        //
        //-------------------------------------------------------------------
 
        #region Public Properties
 
        ///  
        /// Collection of ListItems contained in this List.
        ///  
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ListItemCollection ListItems
        {
            get 
            {
                return new ListItemCollection(this, /*isOwnerParent*/true); 
            } 
        }
 
        /// 
        /// DependencyProperty for  property.
        /// 
        public static readonly DependencyProperty MarkerStyleProperty = 
                DependencyProperty.Register(
                        "MarkerStyle", 
                        typeof(TextMarkerStyle), 
                        typeof(List),
                        new FrameworkPropertyMetadata( 
                                TextMarkerStyle.Disc,
                                FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender),
                        new ValidateValueCallback(IsValidMarkerStyle));
 
        /// 
        /// Type of bullet or number to be used by default with ListElementItems 
        /// contained by this List 
        /// 
        public TextMarkerStyle MarkerStyle 
        {
            get { return (TextMarkerStyle)GetValue(MarkerStyleProperty); }
            set { SetValue(MarkerStyleProperty, value); }
        } 

        ///  
        /// DependencyProperty for  property. 
        /// 
        public static readonly DependencyProperty MarkerOffsetProperty = 
                DependencyProperty.Register(
                        "MarkerOffset",
                        typeof(double),
                        typeof(List), 
                        new FrameworkPropertyMetadata(
                                Double.NaN, 
                                FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), 
                                new ValidateValueCallback(IsValidMarkerOffset));
 
        /// 
        /// Desired distance between each contained ListItem's content and
        /// near edge of the associated marker.
        ///  
        [TypeConverter(typeof(LengthConverter))]
        public double MarkerOffset 
        { 
            get { return (double)GetValue(MarkerOffsetProperty); }
            set { SetValue(MarkerOffsetProperty, value); } 
        }

        /// 
        /// DependencyProperty for  property. 
        /// 
        public static readonly DependencyProperty StartIndexProperty = 
                DependencyProperty.Register( 
                        "StartIndex",
                        typeof(int), 
                        typeof(List),
                        new FrameworkPropertyMetadata(
                                1,
                                FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), 
                        new ValidateValueCallback(IsValidStartIndex));
 
        ///  
        /// Item index of the first ListItem that is immediate child of
        /// this List. 
        /// 
        public int StartIndex
        {
            get { return (int)GetValue(StartIndexProperty); } 
            set { SetValue(StartIndexProperty, value); }
        } 
 
        #endregion Public Properties
 
        //--------------------------------------------------------------------
        //
        //  Internal Methods
        // 
        //--------------------------------------------------------------------
 
        #region Internal Methods 

        ///  
        /// Returns the integer "index" of a specified ListItem that is an immediate child of
        /// this List. This index is defined to be a sequential counter of ListElementItems only
        /// (skipping other elements) among this List's immediate children.
        /// 
        /// The list item index of the first child of type ListItem is specified by
        /// this.StartListIndex, which has a default value of 1. 
        /// 
        /// The index returned by this method is used in the formation of some ListItem
        /// markers such as "(b)" and "viii." (as opposed to others, like disks and wedges, 
        /// which are not sequential-position-dependent).
        /// 
        /// The item whose index is to be returned.
        /// Returns the index of a specified ListItem. 
        internal int GetListItemIndex(ListItem item)
        { 
            // Check for valid arg 
            if (item == null)
            { 
                throw new ArgumentNullException("item");
            }
            if (item.Parent != this)
            { 
                throw new InvalidOperationException(SR.Get(SRID.ListElementItemNotAChildOfList));
            } 
 
            // Count ListItem siblings (not other element types) back to first item.
            int itemIndex = StartIndex; 
            TextPointer textNav = new TextPointer(this.ContentStart);
            while (textNav.CompareTo(this.ContentEnd) != 0)
            {
                // ListItem is a content element, so look for ElementStart runs only 
                if (textNav.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart)
                { 
                    DependencyObject element = textNav.GetAdjacentElementFromOuterPosition(LogicalDirection.Forward); 
                    if (element is ListItem)
                    { 
                        if (element == item)
                        {
                            break;
                        } 
                        if (itemIndex < int.MaxValue)
                        { 
                            ++itemIndex; 
                        }
                    } 
                    // Skip entire content element content, because we are looking
                    // only for immediate children.
                    textNav.MoveToPosition(((TextElement)element).ElementEnd);
                } 
                else
                { 
                    textNav.MoveToNextContextPosition(LogicalDirection.Forward); 
                }
            } 
            return itemIndex;
        }

        ///  
        /// Inserts a List around a sequence of Blocks
        /// starting from firstBlock ending with lastBlock. 
        /// the List must be empty and not inserted in a tree 
        /// before the operation
        ///  
        /// 
        /// 
        internal void Apply(Block firstBlock, Block lastBlock)
        { 
            Invariant.Assert(this.Parent == null, "Cannot Apply List Because It Is Inserted In The Tree Already.");
            Invariant.Assert(this.IsEmpty, "Cannot Apply List Because It Is Not Empty."); 
            Invariant.Assert(firstBlock.Parent == lastBlock.Parent, "Cannot Apply List Because Block Are Not Siblings."); 

            TextContainer textContainer = this.TextContainer; 

            textContainer.BeginChange();
            try
            { 
                // Wrap all block items into this List element
                this.Reposition(firstBlock.ElementStart, lastBlock.ElementEnd); 
 
                // Add ListItem elements
                Block block = firstBlock; 
                while (block != null)
                {
                    ListItem listItem;
                    if (block is List) 
                    {
                        // To wrap List into list item we pull it into previous ListItem (if any) as sublist 
                        listItem = block.ElementStart.GetAdjacentElement(LogicalDirection.Backward) as ListItem; 
                        if (listItem != null)
                        { 
                            // Wrap the List into preceding ListItem
                            listItem.Reposition(listItem.ContentStart, block.ElementEnd);
                        }
                        else 
                        {
                            // No preceding ListItem. Create new one 
                            listItem = new ListItem(); 
                            listItem.Reposition(block.ElementStart, block.ElementEnd);
                        } 
                    }
                    else
                    {
                        // To wrap paragraph into list item we need to create a new one 
                        //
                        listItem = new ListItem(); 
                        listItem.Reposition(block.ElementStart, block.ElementEnd); 

                        // MS Word-like heuristic: clear margin from a paragraph before wrapping it into a list item 
                        // Note: using TextContainer to make sure that undo unit is created.
                        block.ClearValue(Block.MarginProperty);
                        block.ClearValue(Block.PaddingProperty);
                        block.ClearValue(Paragraph.TextIndentProperty); 
                    }
 
                    // Stop when the last paragraph is covered 
                    block = block == lastBlock ? null : (Block)listItem.ElementEnd.GetAdjacentElement(LogicalDirection.Forward);
                } 

                // We need to set appropriate FlowDirection property on the new List and its paragraph children.
                // We take the FlowDirection value from the first paragraph's FlowDirection value.
 
                TextRangeEdit.SetParagraphProperty(this.ElementStart, this.ElementEnd,
                    Paragraph.FlowDirectionProperty, firstBlock.GetValue(Paragraph.FlowDirectionProperty)); 
            } 
            finally
            { 
                textContainer.EndChange();
            }
        }
 
        #endregion Internal Methods
 
        //------------------------------------------------------------------- 
        //
        // Private Methods 
        //
        //--------------------------------------------------------------------

        #region Private Methods 

        private static bool IsValidMarkerStyle(object o) 
        { 
            TextMarkerStyle value = (TextMarkerStyle)o;
            return value == TextMarkerStyle.None 
                || value == TextMarkerStyle.Disc
                || value == TextMarkerStyle.Circle
                || value == TextMarkerStyle.Square
                || value == TextMarkerStyle.Box 
                || value == TextMarkerStyle.LowerRoman
                || value == TextMarkerStyle.UpperRoman 
                || value == TextMarkerStyle.LowerLatin 
                || value == TextMarkerStyle.UpperLatin
                || value == TextMarkerStyle.Decimal; 
        }

        private static bool IsValidStartIndex(object o)
        { 
            int value = (int)o;
            return (value > 0); 
        } 

        private static bool IsValidMarkerOffset(object o) 
        {
            double value = (double)o;
            double maxOffset = Math.Min(1000000, PTS.MaxPageSize);
            double minOffset = -maxOffset; 

            if (Double.IsNaN(value)) 
            { 
                // Default
                return true; 
            }
            if (value < minOffset || value > maxOffset)
            {
                return false; 
            }
            return true; 
        } 

        #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