PasswordTextNavigator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / System / Windows / Controls / PasswordTextNavigator.cs / 1 / PasswordTextNavigator.cs

                            //---------------------------------------------------------------------------- 
//
// File: PasswordTextPointer.cs
//
// Copyright (C) Microsoft Corporation.  All rights reserved. 
//
// Description: An override class representing a movable 
//              position within a PasswordTextContainer. 
//
//--------------------------------------------------------------------------- 

namespace System.Windows.Controls
{
    using System; 
    using System.Windows.Threading;
    using System.Diagnostics; 
    using System.Windows.Documents; 
    using MS.Internal;
 
    // TextNavigator implementation for the PasswordTextContainer.
    internal sealed class PasswordTextPointer : ITextPointer
    {
        //----------------------------------------------------- 
        //
        //  Constructors 
        // 
        //-----------------------------------------------------
 
        #region Constructors

        // Creates a new PasswordTextPointer instance.
        internal PasswordTextPointer(PasswordTextContainer container, LogicalDirection gravity, int offset) 
        {
            Debug.Assert(offset >= 0 && offset <= container.SymbolCount, "Bad PasswordTextPointer offset!"); 
 
            _container = container;
            _gravity = gravity; 
            _offset = offset;

            container.AddPosition(this);
        } 

        #endregion Constructors 
 
        //------------------------------------------------------
        // 
        //  Internal Methods
        //
        //-----------------------------------------------------
 
        #region Internal Methods
 
        ///  
        /// 
        ///  
        void ITextPointer.SetLogicalDirection(LogicalDirection direction)
        {
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");
 
            if (direction != _gravity)
            { 
                // We need to remove the position from the container since we're 
                // going to change its gravity, which changes its internal sort order.
                this.Container.RemovePosition(this); 

                _gravity = direction;

                // Now start tracking the position again, at it's new sort order. 
                this.Container.AddPosition(this);
            } 
        } 

        ///  
        /// Compares this TextPointer with another TextPointer.
        /// 
        /// 
        /// The TextPointer to compare with. 
        /// 
        ///  
        /// Less than zero: this TextPointer preceeds position. 
        /// Zero: this TextPointer is at the same location as position.
        /// Greater than zero: this TextPointer follows position. 
        /// 
        int ITextPointer.CompareTo(ITextPointer position)
        {
            int offset; 
            int result;
 
            offset = ((PasswordTextPointer)position)._offset; 

            if (_offset < offset) 
            {
                result = -1;
            }
            else if (_offset > offset) 
            {
                result = +1; 
            } 
            else
            { 
                result = 0;
            }

            return result; 
        }
 
        int ITextPointer.CompareTo(StaticTextPointer position) 
        {
            return ((ITextPointer)this).CompareTo((ITextPointer)position.Handle0); 
        }

        /// 
        /// Returns the count of symbols between this TextPointer and another. 
        /// 
        ///  
        /// TextPointer to compare. 
        /// 
        ///  
        /// The return value will be negative if
        /// position preceeds this TextPointer, zero if the two TextPositions
        /// are equally positioned, or positive if position follows this
        /// TextPointer. 
        /// 
        int ITextPointer.GetOffsetToPosition(ITextPointer position) 
        { 
            return ((PasswordTextPointer)position)._offset - _offset;
        } 

        /// 
        /// Returns the TextPointerContext of a symbol bordering this TextPointer
        /// in a given direction. 
        /// 
        ///  
        /// Direction to query. 
        /// 
        ///  
        /// Returns TextPointerContext.None if the query is Backward at
        /// TextContainer.Start or Forward at TextContainer.End.
        /// 
        TextPointerContext ITextPointer.GetPointerContext(LogicalDirection direction) 
        {
            TextPointerContext symbolType; 
 
            if ((direction == LogicalDirection.Backward && _offset == 0) ||
                (direction == LogicalDirection.Forward && _offset == _container.SymbolCount)) 
            {
                symbolType = TextPointerContext.None;
            }
            else 
            {
                symbolType = TextPointerContext.Text; 
            } 

            return symbolType; 
        }

        /// 
        /// Returns the count of characters between this TextPointer and the 
        /// next non-Character symbol.
        ///  
        ///  
        /// Direction to query.
        ///  
        /// 
        /// If a non-Character symbol follows immediately in the specified
        /// direction, returns zero.
        /// 
        /// TextContainer implementation does not guarantee that all neighboring
        /// characters are counted, but this method must return values consistent 
        /// with GetText and TextPointerBase.Move. 
        /// 
        int ITextPointer.GetTextRunLength(LogicalDirection direction) 
        {
            int length;

            if (direction == LogicalDirection.Forward) 
            {
                length = _container.SymbolCount - _offset; 
            } 
            else
            { 
                length = _offset;
            }

            return length; 
        }
 
        //  
        string ITextPointer.GetTextInRun(LogicalDirection direction)
        { 
            return TextPointerBase.GetTextInRun(this, direction);
        }

        int ITextPointer.GetTextInRun(LogicalDirection direction, char[] textBuffer, int startIndex, int count) 
        {
            int finalCount; 
            int i; 

            // Truncate based on document size. 
            if (direction == LogicalDirection.Forward)
            {
                finalCount = Math.Min(count, _container.SymbolCount - _offset);
            } 
            else
            { 
                finalCount = Math.Min(count, _offset); 
            }
 
            // Substitute a placeholder char for the real password text.
            char passwordChar = _container.PasswordChar;
            for (i = 0; i < finalCount; i++)
            { 
                textBuffer[startIndex + i] = passwordChar;
            } 
 
            return finalCount;
        } 

        /// 
        /// Returns an embedded object, if any, bordering this TextPointer in the
        /// specified direction. 
        /// 
        ///  
        /// Direction to query. 
        /// 
        ///  
        /// The embedded object, if any exists, otherwise null.
        /// 
        object ITextPointer.GetAdjacentElement(LogicalDirection direction)
        { 
            return null;
        } 
 
        /// 
        /// Returns the type of the text element whose edge is in a specified 
        /// direction from position.
        /// 
        /// 
        /// Direction to query. 
        /// 
        ///  
        /// If the symbol in the specified direction is 
        /// TextPointerContext.ElementStart or TextPointerContext.ElementEnd, then this
        /// method will return the type of element whose edge preceeds this 
        /// TextPointer.
        ///
        /// Otherwise, the method returns null.
        ///  
        Type ITextPointer.GetElementType(LogicalDirection direction)
        { 
            return null; 
        }
 
        /// 
        /// Tests if this position has the same scoping element as
        /// another one.
        ///  
        /// 
        /// Position to compare. 
        ///  
        /// 
        /// true if the scoping element for this position is the same 
        /// instance as the one for a position passed as a parameter,
        /// or if the both positions have no scoping element.
        ///
        /// false otherwise. 
        /// 
        bool ITextPointer.HasEqualScope(ITextPointer position) 
        { 
            return true;
        } 

        /// 
        /// Returns the value of a DependencyProperty at the specified position.
        ///  
        /// 
        /// Property to query. 
        ///  
        /// 
        /// Returns the value of the specified property at position. 
        /// If the position has no scoping text element, and the TextContainer
        /// has a null Parent property, returns DependencyProperty.UnsetValue.
        /// 
        ///  
        /// This method considers inherited values from the containing control.
        /// This method will return property values even from positions with 
        /// no scoping element (when GetElement returns null). 
        /// 
        object ITextPointer.GetValue(DependencyProperty formattingProperty) 
        {
            return _container.PasswordBox.GetValue(formattingProperty);
        }
 
        /// 
        /// Returns the local value of a DependencyProperty at the specified position. 
        ///  
        /// 
        /// Property to query. 
        /// 
        object ITextPointer.ReadLocalValue(DependencyProperty formattingProperty)
        {
            // This method should never be called because we never have a scoping element. 
            Debug.Assert(false);
            return DependencyProperty.UnsetValue; 
        } 

        ///  
        /// Returns an enumerator for property values declared locally on this
        /// TextPointer's scoping element.  If there is no scoping element,
        /// returns an empty enumerator.
        ///  
        LocalValueEnumerator ITextPointer.GetLocalValueEnumerator()
        { 
            return (new DependencyObject()).GetLocalValueEnumerator(); 
        }
 
        ITextPointer ITextPointer.CreatePointer()
        {
            return new PasswordTextPointer(_container, _gravity, _offset);
        } 

        // Unoptimized CreateStaticPointer implementation. 
        // Creates a simple wrapper for an ITextPointer instance. 
        StaticTextPointer ITextPointer.CreateStaticPointer()
        { 
            return new StaticTextPointer(((ITextPointer)this).TextContainer, ((ITextPointer)this).CreatePointer());
        }

        ITextPointer ITextPointer.CreatePointer(int distance) 
        {
            return new PasswordTextPointer(_container, _gravity, _offset + distance); 
        } 

        ITextPointer ITextPointer.CreatePointer(LogicalDirection gravity) 
        {
            return new PasswordTextPointer(_container, gravity, _offset);
        }
 
        /// 
        /// Returns an immutable TextPointer located at some distance 
        /// relative to this TextPointer. 
        /// 
        ///  
        /// Distance, in symbols, of the new TextPointer relative to this one.
        /// distance may be negative, placing the new TextPositon behind this
        /// one.
        ///  
        /// 
        /// Gravity of the new TextPointer. 
        ///  
        /// 
        /// The returned position may be the same instance as the calling 
        /// position if distance is zero and this TextPointer is immutable with
        /// equal gravity.
        /// 
        ITextPointer ITextPointer.CreatePointer(int distance, LogicalDirection gravity) 
        {
            return new PasswordTextPointer(_container, gravity, _offset + distance); 
        } 

        //  
        void ITextPointer.Freeze()
        {
            _isFrozen = true;
        } 

        ///  
        ///  
        /// 
        ITextPointer ITextPointer.GetFrozenPointer(LogicalDirection logicalDirection) 
        {
            return TextPointerBase.GetFrozenPointer(this, logicalDirection);
        }
 
        /// 
        /// Inserts text at a specified position. 
        ///  
        /// 
        /// Text to insert. 
        /// 
        void ITextPointer.InsertTextInRun(string textData)
        {
            _container.InsertText(this, textData); 
        }
 
        ///  
        /// Removes content covered by a pair of positions.
        ///  
        /// 
        /// Position following the last symbol to delete.  endPosition must be
        /// scoped by the same text element as startPosition.
        ///  
        void ITextPointer.DeleteContentToPosition(ITextPointer limit)
        { 
            _container.DeleteContent(this, limit); 
        }
 
        /// 
        /// Advances this TextNavigator over one or more symbols -- a single
        /// ElementStart/End or Object symbol, or a group of neighboring
        /// Character symbols. 
        /// 
        ///  
        /// Direction to move. 
        /// 
        ///  
        /// true if the navigator is repositioned, false if the navigator
        /// borders the start or end of the TextContainer.
        /// 
        ///  
        /// If the following symbol is of type EmbeddedObject, ElementBegin,
        /// or ElementEnd, this TextNavigator is advanced by exactly one symbol. 
        /// 
        /// If the following symbol is of type Character, this TextNavigator is
        /// advanced by some number of Character symbols.  The exact value can 
        /// determined in advance by calling TextPointer.GetTextLength at the
        /// current position.  The movement distance is not guaranteed to
        /// include all neighboring characters, but it must be consistent with
        /// TextPointer.GetTextLength and TextContainer.GetText. 
        ///
        /// If there is no following symbol in the indicated direction, this 
        /// TextNavigator is not repositioned and the method returns 
        /// TextPointerContext.None.
        ///  
        bool ITextPointer.MoveToNextContextPosition(LogicalDirection direction)
        {
            int offset;
 
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");
 
            if (direction == LogicalDirection.Backward) 
            {
                if (this.Offset == 0) 
                {
                    return false;
                }
                offset = 0; 
            }
            else 
            { 
                if (this.Offset == this.Container.SymbolCount)
                { 
                    return false;
                }
                offset = this.Container.SymbolCount;
            } 

            this.Container.RemovePosition(this); 
 
            this.Offset = offset;
 
            this.Container.AddPosition(this);

            return true;
        } 

        ///  
        /// Repositions this TextNavigator at a symbol offset relative to 
        /// its current position.
        ///  
        /// 
        /// The offset count, in symbols.  This value may be
        /// negative, positioning this TextNavigator behind its current
        /// position. 
        /// 
        int ITextPointer.MoveByOffset(int distance) 
        { 
            int offset;
 
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");

            offset = this.Offset + distance;
 
            if (offset < 0 || offset > this.Container.SymbolCount)
            { 
                Debug.Assert(false, "Bad distance!"); 
            }
 
            this.Container.RemovePosition(this);

            this.Offset = offset;
 
            this.Container.AddPosition(this);
 
            return distance; 
        }
 
        /// 
        /// Repositions this TextNavigator at the location of a TextPointer.
        /// 
        ///  
        /// TextPointer to move to.
        ///  
        void ITextPointer.MoveToPosition(ITextPointer position) 
        {
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); 

            this.Container.RemovePosition(this);

            this.Offset = ((PasswordTextPointer)position).Offset; 

            this.Container.AddPosition(this); 
        } 

        ///  
        /// Repositions this TextNavigator at an element edge of its scoping
        /// text element.
        /// 
        ///  
        /// The specific edge to move to.
        ///  
        void ITextPointer.MoveToElementEdge(ElementEdge edge) 
        {
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); 
            Debug.Assert(false, "No scoping element!");
        }

        //  
        int ITextPointer.MoveToLineBoundary(int count)
        { 
            return TextPointerBase.MoveToLineBoundary(this, _container.TextView, count); 
        }
 
        // 
        Rect ITextPointer.GetCharacterRect(LogicalDirection direction)
        {
            return TextPointerBase.GetCharacterRect(this, direction); 
        }
 
        bool ITextPointer.MoveToInsertionPosition(LogicalDirection direction) 
        {
            return TextPointerBase.MoveToInsertionPosition(this, direction); 
        }

        bool ITextPointer.MoveToNextInsertionPosition(LogicalDirection direction)
        { 
            return TextPointerBase.MoveToNextInsertionPosition(this, direction);
        } 
 

        // Candidate for replacing MoveToNextContextPosition for immutable TextPointer model 
        ITextPointer ITextPointer.GetNextContextPosition(LogicalDirection direction)
        {
            ITextPointer pointer = ((ITextPointer)this).CreatePointer();
            if (pointer.MoveToNextContextPosition(direction)) 
            {
                pointer.Freeze(); 
            } 
            else
            { 
                pointer = null;
            }
            return pointer;
        } 

        // Candidate for replacing MoveToInsertionPosition for immutable TextPointer model 
        ITextPointer ITextPointer.GetInsertionPosition(LogicalDirection direction) 
        {
            ITextPointer pointer = ((ITextPointer)this).CreatePointer(); 
            pointer.MoveToInsertionPosition(direction);
            pointer.Freeze();
            return pointer;
        } 

        // Candidate for replacing MoveToNextInsertionPosition for immutable TextPointer model 
        ITextPointer ITextPointer.GetNextInsertionPosition(LogicalDirection direction) 
        {
            ITextPointer pointer = ((ITextPointer)this).CreatePointer(); 
            if (pointer.MoveToNextInsertionPosition(direction))
            {
                pointer.Freeze();
            } 
            else
            { 
                pointer = null; 
            }
            return pointer; 
        }

        // Returns the closest insertion position, treating all unicode code points
        // as valid insertion positions.  A useful performance win over 
        // GetNextInsertionPosition when only formatting scopes are important.
        ITextPointer ITextPointer.GetFormatNormalizedPosition(LogicalDirection direction) 
        { 
            ITextPointer pointer = ((ITextPointer)this).CreatePointer();
            TextPointerBase.MoveToFormatNormalizedPosition(pointer, direction); 
            pointer.Freeze();
            return pointer;
        }
 
        /// 
        bool ITextPointer.ValidateLayout() 
        { 
            return TextPointerBase.ValidateLayout(this, _container.TextView);
        } 

        #endregion Internal Methods

        //------------------------------------------------------ 
        //
        //  Internal Properties 
        // 
        //------------------------------------------------------
 
        #region Internal Properties

        // 
        Type ITextPointer.ParentType 
        {
            get 
            { 
                return null;
            } 
        }

        // The PasswordTextContainer associated with this PasswordTextPointer.
        ITextContainer ITextPointer.TextContainer 
        {
            get 
            { 
                return _container;
            } 
        }

        // 
        bool ITextPointer.HasValidLayout 
        {
            get 
            { 
                return (_container.TextView != null && _container.TextView.IsValid && _container.TextView.Contains(this));
            } 
        }

        // 
        bool ITextPointer.IsAtCaretUnitBoundary 
        {
            get 
            { 
                // Because the PasswordTextContainer only ever contains PasswordChars
                // (as far as the renderer is concerned) all positions are caret 
                // unit boundaries.
                return true;
            }
        } 

        ///  
        /// Returns the gravity of this TextPointer. 
        /// 
        ///  
        /// Gravity determines where a TextPointer moves after an insertion of
        /// content at its location.  Backward gravity implies the TextPointer
        /// sticks with its preceding symbol; forward gravity implies the TextPointer
        /// sticks with its following symbol. 
        /// 
        LogicalDirection ITextPointer.LogicalDirection 
        { 
            get
            { 
                return _gravity;
            }
        }
 
        bool ITextPointer.IsAtInsertionPosition
        { 
            get { return TextPointerBase.IsAtInsertionPosition(this); } 
        }
 
        // 
        bool ITextPointer.IsFrozen
        {
            get 
            {
                return _isFrozen; 
            } 
        }
 
        // 
        int ITextPointer.Offset
        {
            get 
            {
                return TextPointerBase.GetOffset(this); 
            } 
        }
 
        // Offset in unicode chars within the document.
        int ITextPointer.CharOffset
        {
            get 
            {
                return this.Offset; 
            } 
        }
 
        // The PasswordTextContainer associated with this PasswordTextPointer.
        internal PasswordTextContainer Container
        {
            get 
            {
                return _container; 
            } 
            // setter removed (unused internal API).  If needed, recall from history.
        } 

        // This PasswordTextPointer's gravity.
        internal LogicalDirection LogicalDirection
        { 
            get
            { 
                return _gravity; 
            }
            // setter removed (unused internal API).  If needed, recall from history. 
        }

        // The offset, in symbols, of this PasswordTextPointer.
        // NB: do not modify this value directly unless you have first removed 
        // the positoin from PasswordTextContainer's _positionList with
        // PasswordTextContainter.RemovePosition!  Failure to do so will break 
        // the list's sort order. 
        internal int Offset
        { 
            get
            {
                return _offset;
            } 

            set 
            { 
                _offset = value;
            } 
        }

#if DEBUG
        // Unique debug-only identifier for this instance. 
        internal int DebugId
        { 
            get 
            {
                return _debugId; 
            }
        }
#endif // DEBUG
 
        #endregion Internal Properties
 
        //----------------------------------------------------- 
        //
        //  Private Fields 
        //
        //------------------------------------------------------

        #region Private Fields 

        // The PasswordTextContainer associated with this PasswordTextPointer. 
        private PasswordTextContainer _container; 

        // This position's gravity. 
        private LogicalDirection _gravity;

        // The offset, in symbols, of this PasswordTextPointer.
        // NB: do not modify this value directly unless you have first removed 
        // the positoin from PasswordTextContainer's _positionList with
        // PasswordTextContainter.RemovePosition!  Failure to do so will break 
        // the list's sort order. 
        private int _offset;
 
        // True if Freeze has been called, in which case
        // this TextPointer is immutable and may not be repositioned.
        private bool _isFrozen;
 
#if DEBUG
        private static int _debugIdCounter; 
 
        // Unique debug-only identifier for this instance.
        private int _debugId = _debugIdCounter++; 
#endif

        #endregion Private Fields
 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// File: PasswordTextPointer.cs
//
// Copyright (C) Microsoft Corporation.  All rights reserved. 
//
// Description: An override class representing a movable 
//              position within a PasswordTextContainer. 
//
//--------------------------------------------------------------------------- 

namespace System.Windows.Controls
{
    using System; 
    using System.Windows.Threading;
    using System.Diagnostics; 
    using System.Windows.Documents; 
    using MS.Internal;
 
    // TextNavigator implementation for the PasswordTextContainer.
    internal sealed class PasswordTextPointer : ITextPointer
    {
        //----------------------------------------------------- 
        //
        //  Constructors 
        // 
        //-----------------------------------------------------
 
        #region Constructors

        // Creates a new PasswordTextPointer instance.
        internal PasswordTextPointer(PasswordTextContainer container, LogicalDirection gravity, int offset) 
        {
            Debug.Assert(offset >= 0 && offset <= container.SymbolCount, "Bad PasswordTextPointer offset!"); 
 
            _container = container;
            _gravity = gravity; 
            _offset = offset;

            container.AddPosition(this);
        } 

        #endregion Constructors 
 
        //------------------------------------------------------
        // 
        //  Internal Methods
        //
        //-----------------------------------------------------
 
        #region Internal Methods
 
        ///  
        /// 
        ///  
        void ITextPointer.SetLogicalDirection(LogicalDirection direction)
        {
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");
 
            if (direction != _gravity)
            { 
                // We need to remove the position from the container since we're 
                // going to change its gravity, which changes its internal sort order.
                this.Container.RemovePosition(this); 

                _gravity = direction;

                // Now start tracking the position again, at it's new sort order. 
                this.Container.AddPosition(this);
            } 
        } 

        ///  
        /// Compares this TextPointer with another TextPointer.
        /// 
        /// 
        /// The TextPointer to compare with. 
        /// 
        ///  
        /// Less than zero: this TextPointer preceeds position. 
        /// Zero: this TextPointer is at the same location as position.
        /// Greater than zero: this TextPointer follows position. 
        /// 
        int ITextPointer.CompareTo(ITextPointer position)
        {
            int offset; 
            int result;
 
            offset = ((PasswordTextPointer)position)._offset; 

            if (_offset < offset) 
            {
                result = -1;
            }
            else if (_offset > offset) 
            {
                result = +1; 
            } 
            else
            { 
                result = 0;
            }

            return result; 
        }
 
        int ITextPointer.CompareTo(StaticTextPointer position) 
        {
            return ((ITextPointer)this).CompareTo((ITextPointer)position.Handle0); 
        }

        /// 
        /// Returns the count of symbols between this TextPointer and another. 
        /// 
        ///  
        /// TextPointer to compare. 
        /// 
        ///  
        /// The return value will be negative if
        /// position preceeds this TextPointer, zero if the two TextPositions
        /// are equally positioned, or positive if position follows this
        /// TextPointer. 
        /// 
        int ITextPointer.GetOffsetToPosition(ITextPointer position) 
        { 
            return ((PasswordTextPointer)position)._offset - _offset;
        } 

        /// 
        /// Returns the TextPointerContext of a symbol bordering this TextPointer
        /// in a given direction. 
        /// 
        ///  
        /// Direction to query. 
        /// 
        ///  
        /// Returns TextPointerContext.None if the query is Backward at
        /// TextContainer.Start or Forward at TextContainer.End.
        /// 
        TextPointerContext ITextPointer.GetPointerContext(LogicalDirection direction) 
        {
            TextPointerContext symbolType; 
 
            if ((direction == LogicalDirection.Backward && _offset == 0) ||
                (direction == LogicalDirection.Forward && _offset == _container.SymbolCount)) 
            {
                symbolType = TextPointerContext.None;
            }
            else 
            {
                symbolType = TextPointerContext.Text; 
            } 

            return symbolType; 
        }

        /// 
        /// Returns the count of characters between this TextPointer and the 
        /// next non-Character symbol.
        ///  
        ///  
        /// Direction to query.
        ///  
        /// 
        /// If a non-Character symbol follows immediately in the specified
        /// direction, returns zero.
        /// 
        /// TextContainer implementation does not guarantee that all neighboring
        /// characters are counted, but this method must return values consistent 
        /// with GetText and TextPointerBase.Move. 
        /// 
        int ITextPointer.GetTextRunLength(LogicalDirection direction) 
        {
            int length;

            if (direction == LogicalDirection.Forward) 
            {
                length = _container.SymbolCount - _offset; 
            } 
            else
            { 
                length = _offset;
            }

            return length; 
        }
 
        //  
        string ITextPointer.GetTextInRun(LogicalDirection direction)
        { 
            return TextPointerBase.GetTextInRun(this, direction);
        }

        int ITextPointer.GetTextInRun(LogicalDirection direction, char[] textBuffer, int startIndex, int count) 
        {
            int finalCount; 
            int i; 

            // Truncate based on document size. 
            if (direction == LogicalDirection.Forward)
            {
                finalCount = Math.Min(count, _container.SymbolCount - _offset);
            } 
            else
            { 
                finalCount = Math.Min(count, _offset); 
            }
 
            // Substitute a placeholder char for the real password text.
            char passwordChar = _container.PasswordChar;
            for (i = 0; i < finalCount; i++)
            { 
                textBuffer[startIndex + i] = passwordChar;
            } 
 
            return finalCount;
        } 

        /// 
        /// Returns an embedded object, if any, bordering this TextPointer in the
        /// specified direction. 
        /// 
        ///  
        /// Direction to query. 
        /// 
        ///  
        /// The embedded object, if any exists, otherwise null.
        /// 
        object ITextPointer.GetAdjacentElement(LogicalDirection direction)
        { 
            return null;
        } 
 
        /// 
        /// Returns the type of the text element whose edge is in a specified 
        /// direction from position.
        /// 
        /// 
        /// Direction to query. 
        /// 
        ///  
        /// If the symbol in the specified direction is 
        /// TextPointerContext.ElementStart or TextPointerContext.ElementEnd, then this
        /// method will return the type of element whose edge preceeds this 
        /// TextPointer.
        ///
        /// Otherwise, the method returns null.
        ///  
        Type ITextPointer.GetElementType(LogicalDirection direction)
        { 
            return null; 
        }
 
        /// 
        /// Tests if this position has the same scoping element as
        /// another one.
        ///  
        /// 
        /// Position to compare. 
        ///  
        /// 
        /// true if the scoping element for this position is the same 
        /// instance as the one for a position passed as a parameter,
        /// or if the both positions have no scoping element.
        ///
        /// false otherwise. 
        /// 
        bool ITextPointer.HasEqualScope(ITextPointer position) 
        { 
            return true;
        } 

        /// 
        /// Returns the value of a DependencyProperty at the specified position.
        ///  
        /// 
        /// Property to query. 
        ///  
        /// 
        /// Returns the value of the specified property at position. 
        /// If the position has no scoping text element, and the TextContainer
        /// has a null Parent property, returns DependencyProperty.UnsetValue.
        /// 
        ///  
        /// This method considers inherited values from the containing control.
        /// This method will return property values even from positions with 
        /// no scoping element (when GetElement returns null). 
        /// 
        object ITextPointer.GetValue(DependencyProperty formattingProperty) 
        {
            return _container.PasswordBox.GetValue(formattingProperty);
        }
 
        /// 
        /// Returns the local value of a DependencyProperty at the specified position. 
        ///  
        /// 
        /// Property to query. 
        /// 
        object ITextPointer.ReadLocalValue(DependencyProperty formattingProperty)
        {
            // This method should never be called because we never have a scoping element. 
            Debug.Assert(false);
            return DependencyProperty.UnsetValue; 
        } 

        ///  
        /// Returns an enumerator for property values declared locally on this
        /// TextPointer's scoping element.  If there is no scoping element,
        /// returns an empty enumerator.
        ///  
        LocalValueEnumerator ITextPointer.GetLocalValueEnumerator()
        { 
            return (new DependencyObject()).GetLocalValueEnumerator(); 
        }
 
        ITextPointer ITextPointer.CreatePointer()
        {
            return new PasswordTextPointer(_container, _gravity, _offset);
        } 

        // Unoptimized CreateStaticPointer implementation. 
        // Creates a simple wrapper for an ITextPointer instance. 
        StaticTextPointer ITextPointer.CreateStaticPointer()
        { 
            return new StaticTextPointer(((ITextPointer)this).TextContainer, ((ITextPointer)this).CreatePointer());
        }

        ITextPointer ITextPointer.CreatePointer(int distance) 
        {
            return new PasswordTextPointer(_container, _gravity, _offset + distance); 
        } 

        ITextPointer ITextPointer.CreatePointer(LogicalDirection gravity) 
        {
            return new PasswordTextPointer(_container, gravity, _offset);
        }
 
        /// 
        /// Returns an immutable TextPointer located at some distance 
        /// relative to this TextPointer. 
        /// 
        ///  
        /// Distance, in symbols, of the new TextPointer relative to this one.
        /// distance may be negative, placing the new TextPositon behind this
        /// one.
        ///  
        /// 
        /// Gravity of the new TextPointer. 
        ///  
        /// 
        /// The returned position may be the same instance as the calling 
        /// position if distance is zero and this TextPointer is immutable with
        /// equal gravity.
        /// 
        ITextPointer ITextPointer.CreatePointer(int distance, LogicalDirection gravity) 
        {
            return new PasswordTextPointer(_container, gravity, _offset + distance); 
        } 

        //  
        void ITextPointer.Freeze()
        {
            _isFrozen = true;
        } 

        ///  
        ///  
        /// 
        ITextPointer ITextPointer.GetFrozenPointer(LogicalDirection logicalDirection) 
        {
            return TextPointerBase.GetFrozenPointer(this, logicalDirection);
        }
 
        /// 
        /// Inserts text at a specified position. 
        ///  
        /// 
        /// Text to insert. 
        /// 
        void ITextPointer.InsertTextInRun(string textData)
        {
            _container.InsertText(this, textData); 
        }
 
        ///  
        /// Removes content covered by a pair of positions.
        ///  
        /// 
        /// Position following the last symbol to delete.  endPosition must be
        /// scoped by the same text element as startPosition.
        ///  
        void ITextPointer.DeleteContentToPosition(ITextPointer limit)
        { 
            _container.DeleteContent(this, limit); 
        }
 
        /// 
        /// Advances this TextNavigator over one or more symbols -- a single
        /// ElementStart/End or Object symbol, or a group of neighboring
        /// Character symbols. 
        /// 
        ///  
        /// Direction to move. 
        /// 
        ///  
        /// true if the navigator is repositioned, false if the navigator
        /// borders the start or end of the TextContainer.
        /// 
        ///  
        /// If the following symbol is of type EmbeddedObject, ElementBegin,
        /// or ElementEnd, this TextNavigator is advanced by exactly one symbol. 
        /// 
        /// If the following symbol is of type Character, this TextNavigator is
        /// advanced by some number of Character symbols.  The exact value can 
        /// determined in advance by calling TextPointer.GetTextLength at the
        /// current position.  The movement distance is not guaranteed to
        /// include all neighboring characters, but it must be consistent with
        /// TextPointer.GetTextLength and TextContainer.GetText. 
        ///
        /// If there is no following symbol in the indicated direction, this 
        /// TextNavigator is not repositioned and the method returns 
        /// TextPointerContext.None.
        ///  
        bool ITextPointer.MoveToNextContextPosition(LogicalDirection direction)
        {
            int offset;
 
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");
 
            if (direction == LogicalDirection.Backward) 
            {
                if (this.Offset == 0) 
                {
                    return false;
                }
                offset = 0; 
            }
            else 
            { 
                if (this.Offset == this.Container.SymbolCount)
                { 
                    return false;
                }
                offset = this.Container.SymbolCount;
            } 

            this.Container.RemovePosition(this); 
 
            this.Offset = offset;
 
            this.Container.AddPosition(this);

            return true;
        } 

        ///  
        /// Repositions this TextNavigator at a symbol offset relative to 
        /// its current position.
        ///  
        /// 
        /// The offset count, in symbols.  This value may be
        /// negative, positioning this TextNavigator behind its current
        /// position. 
        /// 
        int ITextPointer.MoveByOffset(int distance) 
        { 
            int offset;
 
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");

            offset = this.Offset + distance;
 
            if (offset < 0 || offset > this.Container.SymbolCount)
            { 
                Debug.Assert(false, "Bad distance!"); 
            }
 
            this.Container.RemovePosition(this);

            this.Offset = offset;
 
            this.Container.AddPosition(this);
 
            return distance; 
        }
 
        /// 
        /// Repositions this TextNavigator at the location of a TextPointer.
        /// 
        ///  
        /// TextPointer to move to.
        ///  
        void ITextPointer.MoveToPosition(ITextPointer position) 
        {
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); 

            this.Container.RemovePosition(this);

            this.Offset = ((PasswordTextPointer)position).Offset; 

            this.Container.AddPosition(this); 
        } 

        ///  
        /// Repositions this TextNavigator at an element edge of its scoping
        /// text element.
        /// 
        ///  
        /// The specific edge to move to.
        ///  
        void ITextPointer.MoveToElementEdge(ElementEdge edge) 
        {
            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); 
            Debug.Assert(false, "No scoping element!");
        }

        //  
        int ITextPointer.MoveToLineBoundary(int count)
        { 
            return TextPointerBase.MoveToLineBoundary(this, _container.TextView, count); 
        }
 
        // 
        Rect ITextPointer.GetCharacterRect(LogicalDirection direction)
        {
            return TextPointerBase.GetCharacterRect(this, direction); 
        }
 
        bool ITextPointer.MoveToInsertionPosition(LogicalDirection direction) 
        {
            return TextPointerBase.MoveToInsertionPosition(this, direction); 
        }

        bool ITextPointer.MoveToNextInsertionPosition(LogicalDirection direction)
        { 
            return TextPointerBase.MoveToNextInsertionPosition(this, direction);
        } 
 

        // Candidate for replacing MoveToNextContextPosition for immutable TextPointer model 
        ITextPointer ITextPointer.GetNextContextPosition(LogicalDirection direction)
        {
            ITextPointer pointer = ((ITextPointer)this).CreatePointer();
            if (pointer.MoveToNextContextPosition(direction)) 
            {
                pointer.Freeze(); 
            } 
            else
            { 
                pointer = null;
            }
            return pointer;
        } 

        // Candidate for replacing MoveToInsertionPosition for immutable TextPointer model 
        ITextPointer ITextPointer.GetInsertionPosition(LogicalDirection direction) 
        {
            ITextPointer pointer = ((ITextPointer)this).CreatePointer(); 
            pointer.MoveToInsertionPosition(direction);
            pointer.Freeze();
            return pointer;
        } 

        // Candidate for replacing MoveToNextInsertionPosition for immutable TextPointer model 
        ITextPointer ITextPointer.GetNextInsertionPosition(LogicalDirection direction) 
        {
            ITextPointer pointer = ((ITextPointer)this).CreatePointer(); 
            if (pointer.MoveToNextInsertionPosition(direction))
            {
                pointer.Freeze();
            } 
            else
            { 
                pointer = null; 
            }
            return pointer; 
        }

        // Returns the closest insertion position, treating all unicode code points
        // as valid insertion positions.  A useful performance win over 
        // GetNextInsertionPosition when only formatting scopes are important.
        ITextPointer ITextPointer.GetFormatNormalizedPosition(LogicalDirection direction) 
        { 
            ITextPointer pointer = ((ITextPointer)this).CreatePointer();
            TextPointerBase.MoveToFormatNormalizedPosition(pointer, direction); 
            pointer.Freeze();
            return pointer;
        }
 
        /// 
        bool ITextPointer.ValidateLayout() 
        { 
            return TextPointerBase.ValidateLayout(this, _container.TextView);
        } 

        #endregion Internal Methods

        //------------------------------------------------------ 
        //
        //  Internal Properties 
        // 
        //------------------------------------------------------
 
        #region Internal Properties

        // 
        Type ITextPointer.ParentType 
        {
            get 
            { 
                return null;
            } 
        }

        // The PasswordTextContainer associated with this PasswordTextPointer.
        ITextContainer ITextPointer.TextContainer 
        {
            get 
            { 
                return _container;
            } 
        }

        // 
        bool ITextPointer.HasValidLayout 
        {
            get 
            { 
                return (_container.TextView != null && _container.TextView.IsValid && _container.TextView.Contains(this));
            } 
        }

        // 
        bool ITextPointer.IsAtCaretUnitBoundary 
        {
            get 
            { 
                // Because the PasswordTextContainer only ever contains PasswordChars
                // (as far as the renderer is concerned) all positions are caret 
                // unit boundaries.
                return true;
            }
        } 

        ///  
        /// Returns the gravity of this TextPointer. 
        /// 
        ///  
        /// Gravity determines where a TextPointer moves after an insertion of
        /// content at its location.  Backward gravity implies the TextPointer
        /// sticks with its preceding symbol; forward gravity implies the TextPointer
        /// sticks with its following symbol. 
        /// 
        LogicalDirection ITextPointer.LogicalDirection 
        { 
            get
            { 
                return _gravity;
            }
        }
 
        bool ITextPointer.IsAtInsertionPosition
        { 
            get { return TextPointerBase.IsAtInsertionPosition(this); } 
        }
 
        // 
        bool ITextPointer.IsFrozen
        {
            get 
            {
                return _isFrozen; 
            } 
        }
 
        // 
        int ITextPointer.Offset
        {
            get 
            {
                return TextPointerBase.GetOffset(this); 
            } 
        }
 
        // Offset in unicode chars within the document.
        int ITextPointer.CharOffset
        {
            get 
            {
                return this.Offset; 
            } 
        }
 
        // The PasswordTextContainer associated with this PasswordTextPointer.
        internal PasswordTextContainer Container
        {
            get 
            {
                return _container; 
            } 
            // setter removed (unused internal API).  If needed, recall from history.
        } 

        // This PasswordTextPointer's gravity.
        internal LogicalDirection LogicalDirection
        { 
            get
            { 
                return _gravity; 
            }
            // setter removed (unused internal API).  If needed, recall from history. 
        }

        // The offset, in symbols, of this PasswordTextPointer.
        // NB: do not modify this value directly unless you have first removed 
        // the positoin from PasswordTextContainer's _positionList with
        // PasswordTextContainter.RemovePosition!  Failure to do so will break 
        // the list's sort order. 
        internal int Offset
        { 
            get
            {
                return _offset;
            } 

            set 
            { 
                _offset = value;
            } 
        }

#if DEBUG
        // Unique debug-only identifier for this instance. 
        internal int DebugId
        { 
            get 
            {
                return _debugId; 
            }
        }
#endif // DEBUG
 
        #endregion Internal Properties
 
        //----------------------------------------------------- 
        //
        //  Private Fields 
        //
        //------------------------------------------------------

        #region Private Fields 

        // The PasswordTextContainer associated with this PasswordTextPointer. 
        private PasswordTextContainer _container; 

        // This position's gravity. 
        private LogicalDirection _gravity;

        // The offset, in symbols, of this PasswordTextPointer.
        // NB: do not modify this value directly unless you have first removed 
        // the positoin from PasswordTextContainer's _positionList with
        // PasswordTextContainter.RemovePosition!  Failure to do so will break 
        // the list's sort order. 
        private int _offset;
 
        // True if Freeze has been called, in which case
        // this TextPointer is immutable and may not be repositioned.
        private bool _isFrozen;
 
#if DEBUG
        private static int _debugIdCounter; 
 
        // Unique debug-only identifier for this instance.
        private int _debugId = _debugIdCounter++; 
#endif

        #endregion Private Fields
 
    }
} 

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