PasswordBox.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Controls / PasswordBox.cs / 1 / PasswordBox.cs

                            //---------------------------------------------------------------------------- 
//
// File: PasswordBox.cs
//
// Copyright (C) Microsoft Corporation.  All rights reserved. 
//
// Description: The stock password control. 
// 
//---------------------------------------------------------------------------
 
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Globalization; 
using System.Security;
using System.Text; 
using System.Windows.Media; 
using System.Windows.Data;
using System.Windows.Documents; 
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Input;
using System.Windows.Navigation; 
using System.Windows.Shapes;
using System.Windows.Threading; 
using MS.Internal; 
using MS.Internal.KnownBoxes;
using System.Security.Permissions; 

#pragma warning disable 1634, 1691  // suppressing PreSharp warnings

namespace System.Windows.Controls 
{
    ///  
    /// The stock password control. 
    /// 
#if OLD_AUTOMATION 
    [Automation(AccessibilityControlType = "Edit")]
#endif
    [TemplatePart(Name = "PART_ContentHost", Type = typeof(FrameworkElement))]
    public sealed class PasswordBox : Control, ITextBoxViewHost 
#if OLD_AUTOMATION
        , IAutomationPatternProvider, IAutomationPropertyProvider 
#endif 
    {
        //----------------------------------------------------- 
        //
        //  Constructors
        //
        //----------------------------------------------------- 

        #region Constructors 
 
        /// 
        /// Static constructor for PasswordBox. 
        /// 
        static PasswordBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PasswordBox), new FrameworkPropertyMetadata(typeof(PasswordBox))); 
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(PasswordBox));
 
            // PasswordBox properties 
            // ------------------
            PasswordCharProperty.OverrideMetadata(typeof(PasswordBox), 
                    new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPasswordCharChanged)));

            // Declaree listener for Padding property
            Control.PaddingProperty.OverrideMetadata(typeof(PasswordBox), 
                new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPaddingChanged)));
 
            // Prevent journaling 
            NavigationService.NavigationServiceProperty.OverrideMetadata(typeof(PasswordBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnParentNavigationServiceChanged)));
 
            InputMethod.IsInputMethodEnabledProperty.OverrideMetadata(typeof(PasswordBox),
                    new FrameworkPropertyMetadata(
                            BooleanBoxes.FalseBox,
                            FrameworkPropertyMetadataOptions.Inherits, 
                            null,
                            // 
 
                            new CoerceValueCallback(ForceToFalse)));
        } 

        /// 
        /// Constructor.
        ///  
        public PasswordBox() : base()
        { 
            Initialize(); 
        }
 
        #endregion Constructors

        //------------------------------------------------------
        // 
        //  Public Methods
        // 
        //----------------------------------------------------- 

        #region Public Methods 

        /// 
        /// Replaces the current selection in the passwordbox with the contents
        /// of the Clipboard 
        /// 
        public void Paste() 
        { 
            RoutedCommand command = ApplicationCommands.Paste;
            command.Execute(null, this); 
        }

        /// 
        /// Select all text in the PasswordBox 
        /// 
        public void SelectAll() 
        { 
            Selection.Select(TextContainer.Start, TextContainer.End);
        } 

        /// 
        /// Clear all the content in the PasswordBox control.
        ///  
        public void Clear()
        { 
            this.Password = String.Empty; 
        }
 
        #endregion Public Methods

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

        #region Public Properties 

        /// 
        /// Contents of the PasswordBox.
        ///  
        /// 
        /// Use the SecurePassword property in place of this one when possible. 
        /// Doing so reduces the risk of revealing content that should be kept secret. 
        /// 
        ///  
        /// Critical - The getter elevates to unmanaged code and has unsafe code block.
        ///            The setter calls SetSecurePassword.
        ///
        /// PublicOK: Does not pass unsafe data to native code. 
        ///           Does not pass 2nd party SecureString to SetSecurePassword.
        /// 
        ///  
        [DefaultValue("")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public string Password
        {
            [SecurityCritical]
            get 
            {
                string password; 
 
                using (SecureString securePassword = this.SecurePassword)
                { 
                    IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(securePassword);

                    try
                    { 
                        unsafe
                        { 
                            password = new string((char*)ptr); 
                        }
                    } 
                    finally
                    {
                        System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
                    } 
                }
 
                return password; 
            }
 
            [SecurityCritical]
            set
            {
                if (value == null) 
                {
                    value = String.Empty; 
                } 

                using (SecureString securePassword = new SecureString()) 
                {
                    #pragma warning suppress 6506 // value is set to String.Empty if it was null.
                    for (int i = 0; i < value.Length; i++)
                    { 
                        securePassword.AppendChar(value[i]);
                    } 
 
                    SetSecurePassword(securePassword);
                } 
            }
        }

        ///  
        /// Contents of the PasswordBox.
        ///  
        ///  
        /// Reading the Password always returns a copy which may be safely
        /// Disposed. 
        ///
        /// Setting the value always stores a copy of the supplied value.
        /// 
        ///  
        /// Do not add public setter, see SetSecurePassword comments.
        ///  
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public SecureString SecurePassword
        { 
            get
            {
                return this.TextContainer.GetPasswordCopy();
            } 
        }
 
        ///  
        /// The DependencyID for the PasswordChar property.
        /// Default Value:     '*' 
        /// 
        public static readonly DependencyProperty PasswordCharProperty =
                DependencyProperty.RegisterAttached(
                        "PasswordChar", // Property name 
                        typeof(char), // Property type
                        typeof(PasswordBox), // Property owner 
                        new FrameworkPropertyMetadata('*')); // Flags 

        ///  
        /// Character to display instead of the actual password.
        /// 
        public char PasswordChar
        { 
            get { return (char) GetValue(PasswordCharProperty); }
            set { SetValue(PasswordCharProperty, value); } 
        } 

        ///  
        /// The limit number of characters that the PasswordBox or other editable controls can contain.
        /// if it is 0, means no-limitation.
        /// User can set this value for some simple single line PasswordBox to restrict the text number.
        /// By default it is 0. 
        /// 
        ///  
        /// When this property is set to zero, the maximum length of the text that can be entered 
        /// in the control is limited only by available memory. You can use this property to restrict
        /// the length of text entered in the control for values such as postal codes and telephone numbers. 
        /// You can also use this property to restrict the length of text entered when the data is to be entered
        /// in a database.
        /// You can limit the text entered into the control to the maximum length of the corresponding field in the database.
        /// Note:   In code, you can set the value of the Text property to a value that is larger than 
        /// the value specified by the MaxLength property.
        /// This property only affects text entered into the control at runtime. 
        ///  
        public static readonly DependencyProperty MaxLengthProperty =
                TextBox.MaxLengthProperty.AddOwner(typeof(PasswordBox)); 


        /// 
        /// Maximum number of characters the PasswordBox can accept 
        /// 
        [DefaultValue((int)0)] 
        public int MaxLength 
        {
            get { return (int) GetValue(MaxLengthProperty); } 
            set { SetValue(MaxLengthProperty, value); }
        }

        #endregion Public Properties 

        //----------------------------------------------------- 
        // 
        //  Public Events
        // 
        //------------------------------------------------------

        #region Public Events
 
        /// 
        /// Event for "Text has changed" 
        ///  
        /// 
        /// Unlike most RoutedEvents on Controls, PasswordChangedEvent does not 
        /// have a matching protected virtual OnPasswordChanged method --
        /// because PasswordBox is sealed.
        /// 
        public static readonly RoutedEvent PasswordChangedEvent = EventManager.RegisterRoutedEvent( 
            "PasswordChanged", // Event name
            RoutingStrategy.Bubble, // 
            typeof(RoutedEventHandler), // 
            typeof(PasswordBox)); //
 
        /// 
        /// Event fired from this text box when its inner content
        /// has been changed.
        ///  
        /// 
        /// It is redirected from inner TextContainer.Changed event. 
        ///  
        public event RoutedEventHandler PasswordChanged
        { 
            add
            {
                AddHandler(PasswordChangedEvent, value);
            } 

            remove 
            { 
                RemoveHandler(PasswordChangedEvent, value);
            } 
        }

        #endregion Public Events
 
        //-----------------------------------------------------
        // 
        //  Protected Methods 
        //
        //----------------------------------------------------- 

        #region Protected Methods

        ///  
        /// Creates AutomationPeer ()
        ///  
        protected override AutomationPeer OnCreateAutomationPeer() 
        {
            return new PasswordBoxAutomationPeer(this); 
        }

        /// 
        /// Called when the Template's tree has been generated 
        /// 
        public override void OnApplyTemplate() 
        { 
            base.OnApplyTemplate();
            AttachToVisualTree(); 
        }

        /// 
        /// Template has changed 
        /// 
        ///  
        ///  
        /// 
        ///  
        protected override void OnTemplateChanged(ControlTemplate oldTemplate, ControlTemplate newTemplate)
        {
            base.OnTemplateChanged(oldTemplate, newTemplate);
 
            if (oldTemplate!=null && newTemplate!= null && oldTemplate.VisualTree != newTemplate.VisualTree)
            { 
                DetachFromVisualTree(); 
            }
        } 

        ///
        /// 
        /// 
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        { 
            //  always call base.OnPropertyChanged, otherwise Property Engine will not work. 
            base.OnPropertyChanged(e);
 
            if (this.RenderScope != null)
            {
                FrameworkPropertyMetadata fmetadata = e.Property.GetMetadata(typeof(PasswordBox)) as FrameworkPropertyMetadata;
                if (fmetadata != null) 
                {
                    if (e.IsAValueChange || e.IsASubPropertyChange) 
                    { 
                        if (fmetadata.AffectsMeasure || fmetadata.AffectsArrange ||
                            fmetadata.AffectsParentMeasure || fmetadata.AffectsParentArrange || 
                            e.Property == Control.HorizontalContentAlignmentProperty || e.Property == Control.VerticalContentAlignmentProperty)
                        {
                            ((TextBoxView)this.RenderScope).Remeasure();
                        } 
                        else if (fmetadata.AffectsRender &&
                                (e.IsAValueChange || !fmetadata.SubPropertiesDoNotAffectRender)) 
                        { 
                            ((TextBoxView)this.RenderScope).Rerender();
                        } 
                    }
                }
            }
        } 

        ///  
        ///     Virtual method reporting a key was pressed 
        /// 
        protected override void OnKeyDown(KeyEventArgs e) 
        {
            base.OnKeyDown(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnKeyDown(e); 
        }

        /// 
        ///     Virtual method reporting a key was released 
        /// 
        protected override void OnKeyUp(KeyEventArgs e) 
        { 
            base.OnKeyUp(e);
 
            if (e.Handled)
            {
                return;
            } 

            _textEditor.OnKeyUp(e); 
        } 

        ///  
        ///     Virtual method reporting text composition
        /// 
        protected override void OnTextInput(TextCompositionEventArgs e)
        { 
            base.OnTextInput(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnTextInput(e);
        } 

        ///  
        ///     Virtual method reporting the mouse button was pressed 
        /// 
        protected override void OnMouseDown(MouseButtonEventArgs e) 
        {
            base.OnMouseDown(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnMouseDown(e); 
        }

        /// 
        ///     Virtual method reporting a mouse move 
        /// 
        protected override void OnMouseMove(MouseEventArgs e) 
        { 
            base.OnMouseMove(e);
 
            if (e.Handled)
            {
                return;
            } 

            _textEditor.OnMouseMove(e); 
        } 

        ///  
        ///     Virtual method reporting the mouse button was released
        /// 
        protected override void OnMouseUp(MouseButtonEventArgs e)
        { 
            base.OnMouseUp(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnMouseUp(e);
        } 

        ///  
        ///     Virtual method reporting the cursor to display was requested 
        /// 
        protected override void OnQueryCursor(QueryCursorEventArgs e) 
        {
            base.OnQueryCursor(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnQueryCursor(e); 
        }

        /// 
        ///     Virtual method reporting the query continue drag is going to happen 
        /// 
        protected override void OnQueryContinueDrag(QueryContinueDragEventArgs e) 
        { 
            base.OnQueryContinueDrag(e);
 
            if (e.Handled)
            {
                return;
            } 

            _textEditor.OnQueryContinueDrag(e); 
        } 

        ///  
        ///     Virtual method reporting the give feedback is going to happen
        /// 
        protected override void OnGiveFeedback(GiveFeedbackEventArgs e)
        { 
            base.OnGiveFeedback(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnGiveFeedback(e);
        } 

        ///  
        ///     Virtual method reporting the drag enter is going to happen 
        /// 
        protected override void OnDragEnter(DragEventArgs e) 
        {
            base.OnDragEnter(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnDragEnter(e); 
        }

        /// 
        ///     Virtual method reporting the drag over is going to happen 
        /// 
        protected override void OnDragOver(DragEventArgs e) 
        { 
            base.OnDragOver(e);
 
            if (e.Handled)
            {
                return;
            } 

            _textEditor.OnDragOver(e); 
        } 

        ///  
        ///     Virtual method reporting the drag leave is going to happen
        /// 
        protected override void OnDragLeave(DragEventArgs e)
        { 
            base.OnDragLeave(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnDragLeave(e);
        } 

        ///  
        ///     Virtual method reporting the drag enter is going to happen 
        /// 
        protected override void OnDrop(DragEventArgs e) 
        {
            base.OnDrop(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnDrop(e); 
        }

// Disable CS0688: Method has link demand, but overrides method without link demand.
// In this case, we do not trust the input ContextMenuEventArgs (which may have its 
// UserInitiated bit set), so we do not tolerate this method being called in
// partial trust by a derived class.  However, it is perfectly reasonable for a 
// derived class in partial trust to override this method and bring up a custom menu 
// without any clipboard related items.
#pragma warning disable 688 
        /// 
        ///     Called when ContextMenuOpening is raised on this element.
        /// 
        /// Event arguments 
        /// 
        /// Critical - accepts a parameter which may be used to set the userInitiated 
        ///             bit on a command, which is used for security purposes later. 
        /// Public OK - link demanded.
        ///  
        [SecurityCritical]
        [UIPermissionAttribute(SecurityAction.LinkDemand, Clipboard = UIPermissionClipboard.AllClipboard)]
        protected override void OnContextMenuOpening(ContextMenuEventArgs e)
        { 
            base.OnContextMenuOpening(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnContextMenuOpening(e);
        } 
#pragma warning restore 688
 
        ///  
        ///     Virtual method reporting that the keyboard is focused on this element
        ///  
        protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            base.OnGotKeyboardFocus(e);
 
            if (e.Handled)
            { 
                return; 
            }
 
            _textEditor.OnGotKeyboardFocus(e);
        }

        ///  
        ///     Virtual method reporting that the keyboard is no longer focusekeyboard is no longer focuseed
        ///  
        protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e) 
        {
            base.OnLostKeyboardFocus(e); 

            if (e.Handled)
            {
                return; 
            }
 
            _textEditor.OnLostKeyboardFocus(e); 
        }
 
        /// 
        ///     This method is invoked when the IsFocused property changes to false
        /// 
        /// RoutedEventArgs 
        protected override void OnLostFocus(RoutedEventArgs e)
        { 
            base.OnLostFocus(e); 

            if (e.Handled) 
            {
                return;
            }
 
            _textEditor.OnLostFocus(e);
        } 
 
        #endregion Protected Methods
 
        //-----------------------------------------------------
        //
        //  Internal Properties
        // 
        //------------------------------------------------------
 
        #region Internal Properties 

        ///  
        /// readonly access to internal content control
        /// 
        internal FrameworkElement RenderScope
        { 
            get
            { 
                return _renderScope; 
            }
        } 

        internal ScrollViewer ScrollViewer
        {
            get 
            {
                if (_scrollViewer == null) 
                { 
                    if (_textEditor != null)
                    { 
                        _scrollViewer = _textEditor._Scroller as ScrollViewer;
                    }
                }
                return _scrollViewer; 
            }
        } 
 
        // ITextContainer holding the Control content.
        ITextContainer ITextBoxViewHost.TextContainer 
        {
            get
            {
                return this.TextContainer; 
            }
        } 
 
        // Set true when typography property values are all default values.
        bool ITextBoxViewHost.IsTypographyDefaultValue 
        {
            get
            {
                return true; 
            }
        } 
 
        #endregion Internal Properties
 
        //-----------------------------------------------------
        //
        //  Private Methods
        // 
        //------------------------------------------------------
 
        #region Private Methods 

        // Worker for the ctors, initializes a new PasswordBox instance. 
        private void Initialize()
        {
            // Register static editing command handlers.
            // This only has an effect that first time we make the call. 
            // We don't use the static ctor because there are cases
            // where another control will want to alias our properties 
            // but doesn't need this overhead. 
            TextEditor.RegisterCommandHandlers(typeof(PasswordBox), /*acceptsRichContent:*/false, /*readOnly*/false, /*registerEventListeners*/false);
 
            // Create TextContainer
            InitializeTextContainer(new PasswordTextContainer(this));

            // PasswordBox only accepts plain text, so change TextEditor's default to that. 
            _textEditor.AcceptsRichContent = false;
 
            // PasswordBox does not accetps tabs. 
            _textEditor.AcceptsTab = false;
        } 

        // Attaches this control to a new TextContainer.
        private void InitializeTextContainer(PasswordTextContainer textContainer)
        { 
            Invariant.Assert(textContainer != null);
 
            // Uninitialize previous TextEditor 
            if (_textContainer != null)
            { 
                Invariant.Assert(_textEditor != null);
                Invariant.Assert(_textEditor.TextContainer == _textContainer);

                // Detach existing editor from VisualTree 
                DetachFromVisualTree();
 
                // Discard TextEditor - must release text container 
                _textEditor.OnDetach();
            } 

            // Save text container
            _textContainer = textContainer;
 
            //
            ((ITextContainer)_textContainer).Changed += new TextContainerChangedEventHandler(OnTextContainerChanged); 
 
            // Create a text editor, initialize undo manager for it, and link it to text container
            _textEditor = new TextEditor(_textContainer, this, true); 
        }

        // Disable IME input unconditionally.  We really can't support
        // IMEs in this control, because PasswordTextContainer doesn't 
        // round-trip content, which breaks the cicero contract.
        // Additionally, from a UI standpoint, we don't want to break 
        // user expectations by allowing IME input.  IMEs do cool things 
        // like learn from user corrections, so the same keystroke sequence
        // might produce different text over time. 
        private static object ForceToFalse(DependencyObject d, object value)
        {
            return BooleanBoxes.FalseBox;
        } 

        ///  
        /// Callback for changes to the PasswordChar property. 
        /// 
        private static void OnPasswordCharChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            PasswordBox passwordBox = (PasswordBox)d;

            // Force a layout refresh to display the new char. 
            if (passwordBox._renderScope != null)
            { 
                passwordBox._renderScope.InvalidateMeasure(); 
            }
        } 

        /// 
        /// Handler for text array change notifications.
        ///  
        /// 
        /// sender 
        ///  
        /// 
        /// event args 
        /// 
        private void OnTextContainerChanged(object sender, TextContainerChangedEventArgs e)
        {
            // If only properties on the text changed, don't fire a content change event. 
            // This can happen even in a plain text TextBox if we switch logical trees.
            if (!e.HasContentAddedOrRemoved) 
            { 
                return;
            } 

            RaiseEvent(new RoutedEventArgs(PasswordChangedEvent));
        }
 
        /// 
        /// Walk the visual tree until we find a Text control with IsPasswordBoxContent == true 
        /// and a ScrollViewer 
        /// 
        private void SetRenderScopeToContentHost(TextBoxView renderScope) 
        {
            // Clear the content host from previous render scope (if any)
            ClearContentHost();
 
            // Find ContentHostTemplateName in the style
            _passwordBoxContentHost = GetTemplateChild(ContentHostTemplateName) as FrameworkElement; 
 
            // Note that we allow ContentHostTemplateName to be optional.
            // This simplifies toolability of our control styling. 
            // When the ContentHostTemplateName is not found or incorrect
            // PasswordBox goes into disabled state, but does not throw.

            // Add renderScope as a child of ContentHostTemplateName 
            _renderScope = renderScope;
            if (_passwordBoxContentHost is ScrollViewer) 
            { 
                ScrollViewer scrollViewer = (ScrollViewer)_passwordBoxContentHost;
                if (scrollViewer.Content != null) 
                {
                    throw new NotSupportedException(SR.Get(SRID.TextBoxScrollViewerMarkedAsTextBoxContentMustHaveNoContent));
                }
                else 
                {
                    scrollViewer.Content = _renderScope; 
                } 
            }
            else if (_passwordBoxContentHost is Decorator) 
            {
                Decorator decorator = (Decorator)_passwordBoxContentHost;
                if (decorator.Child != null)
                { 
                    throw new NotSupportedException(SR.Get(SRID.TextBoxDecoratorMarkedAsTextBoxContentMustHaveNoContent));
                } 
                else 
                {
                    decorator.Child = _renderScope; // this may replace old render scope in case of upgrade scenario in TextBox 
                }
            }
            else
            { 
                // When we implement TextContainer setting via TextView interface
                // all text containing element will become allowed here. 
                _renderScope = null; 

                // Explicitly not throwing an exception here when content host = null 
                // -- designers need us to support no content scenarios
                if (_passwordBoxContentHost != null)
                {
                    _passwordBoxContentHost = null; 
                    //
                    throw new NotSupportedException(SR.Get(SRID.PasswordBoxInvalidTextContainer)); 
                } 
            }
 
            // Attach render scope to TextEditor
            InitializeRenderScope();

            FrameworkElement element = _renderScope; 
            while (element != this && element != null)  // checking both just to be safe
            { 
                if (element is Border) 
                {
                    _border = (Border)element; 
                }
                element = element.Parent as FrameworkElement;
            }
        } 

        private void ClearContentHost() 
        { 
            // Detach render scope from TextEditor
            UninitializeRenderScope(); 

            // Render scope has been created by us,
            // so we need to extract if from visual tree.
            if (_passwordBoxContentHost is ScrollViewer) 
            {
                ((ScrollViewer)_passwordBoxContentHost).Content = null; 
            } 
            else if (_passwordBoxContentHost is Decorator)
            { 
                ((Decorator)_passwordBoxContentHost).Child = null;
            }
            else
            { 
                Invariant.Assert(_passwordBoxContentHost == null, "_passwordBoxContentHost must be null here");
            } 
 
            _passwordBoxContentHost = null;
        } 

        // Initializes a new render scope.
        private void InitializeRenderScope()
        { 
            if (_renderScope == null)
            { 
                return; 
            }
 
            // Attach the renderScope to TextEditor as its ITextView member.
            ITextView textview = TextEditor.GetTextView(_renderScope);
            _textEditor.TextView = textview;
            this.TextContainer.TextView = textview; 

            if (this.ScrollViewer != null) 
            { 
                this.ScrollViewer.CanContentScroll = true;
            } 
        }

        // Uninitializes a render scope and clears this control's reference.
        private void UninitializeRenderScope() 
        {
            // Clear TextView property in TextEditor 
            _textEditor.TextView = null; 
        }
 
        // Resets the selection to the start of the content.
        // Called after non-TOM changes to the content, like
        // set_Text
        private void ResetSelection() 
        {
            Select(0, 0); 
 
            if (this.ScrollViewer != null)
            { 
                this.ScrollViewer.ScrollToHome();
            }
        }
 
        /// 
        /// Select the text in the given position and length. 
        ///  
        private void Select(int start, int length)
        { 
            ITextPointer selectionStart;
            ITextPointer selectionEnd;

            //             VerifyAccess(); 
            if (start < 0)
            { 
                throw new ArgumentOutOfRangeException("start", SR.Get(SRID.ParameterCannotBeNegative)); 
            }
 
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", SR.Get(SRID.ParameterCannotBeNegative));
            } 

            // Identify new selection start position 
            selectionStart = this.TextContainer.Start.CreatePointer(); 
            while (start-- > 0 && selectionStart.MoveToNextInsertionPosition(LogicalDirection.Forward))
            { 
            }

            // Identify new selection end position
            selectionEnd = selectionStart.CreatePointer(); 
            while (length-- > 0 && selectionEnd.MoveToNextInsertionPosition(LogicalDirection.Forward))
            { 
            } 

            Selection.Select(selectionStart, selectionEnd); 
        }

        /// 
        /// Callback for TextBox.Padding property setting 
        /// 
        ///  
        /// TextBoxBase on which the property is changed 
        /// 
        /// event args 
        private static void OnPaddingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PasswordBox passwordBox = (PasswordBox)d;
 
            if (passwordBox.ScrollViewer != null)
            { 
                // translate this change into inner property set on ScrollViewer 
                object padding = passwordBox.GetValue(Control.PaddingProperty);
                if (padding is Thickness) 
                {
                    passwordBox.ScrollViewer.Padding = (Thickness)padding;
                }
                else 
                {
                    passwordBox.ScrollViewer.ClearValue(Control.PaddingProperty); 
                } 
            }
        } 

        // Set up listener for Navigating event
        private static void OnParentNavigationServiceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        { 
            PasswordBox passwordBox = (PasswordBox)o;
            NavigationService navService = NavigationService.GetNavigationService(o); 
            if (passwordBox._navigationService != null) 
            {
                passwordBox._navigationService.Navigating -= new NavigatingCancelEventHandler(passwordBox.OnNavigating); 
            }
            if (navService != null)
            {
                navService.Navigating += new NavigatingCancelEventHandler(passwordBox.OnNavigating); 
                passwordBox._navigationService = navService;
            } 
            else 
            {
                passwordBox._navigationService = null; 
            }
        }

        // Clear password on navigation to prevent journaling. 
        private void OnNavigating(Object sender, NavigatingCancelEventArgs e)
        { 
            this.Password = String.Empty; 
        }
 
        /// 
        /// Detaches the editor from old visual tree and attaches it to a new one
        /// 
        private void AttachToVisualTree() 
        {
            DetachFromVisualTree(); 
 
            // Walk the visual tree to find our Text element
            SetRenderScopeToContentHost(new TextBoxView(this)); 

            // Attach scroll handler to the new scroll viewer
            // Note that this.ScrollViewer will walk the tree from current TextEditor's render scope up to its ui scope.
            if (this.ScrollViewer != null) 
            {
                this.ScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden; 
                this.ScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled; 
                this.ScrollViewer.Focusable = false;
 
                if (this.ScrollViewer.Background == null)
                {
                    // prevent hit-testing through padding
                    this.ScrollViewer.Background = Brushes.Transparent; 
                }
                OnPaddingChanged(this, new DependencyPropertyChangedEventArgs()); 
            } 

            // Set border properties 
            if (_border != null)
            {
                _border.Style = null;
            } 
        }
 
        ///  
        /// Clear our layout-specific data, and detach our current renderScope from our text editor.
        ///  
        private void DetachFromVisualTree()
        {
            if (_textEditor != null)
            { 
                _textEditor.Selection.DetachFromVisualTree();
            } 
 
            // Invalidate our cached copy of scroll viewer.
            _scrollViewer = null; 
            _border = null;

            ClearContentHost();
        } 

        ///  
        /// Sets the content of the control. 
        /// 
        ///  
        /// Critical - This method indirectly reveals value's SecureString content.
        ///
        /// This method must never be passed a publicly supplied SecureString as long as we expose
        /// a plain text get_Password property. 
        ///
        /// 1. Attacker sets SecureString value it does not have permission to read. 
        /// 2. Attacker reads Password property. 
        /// --> attacker has ----ed open a SecureString without UnmanagedCode permission.
        ///  
        [SecurityCritical]
        private void SetSecurePassword(SecureString value)
        {
            this.TextContainer.BeginChange(); 
            try
            { 
                this.TextContainer.SetPassword(value); 
                this.ResetSelection();
            } 
            finally
            {
                this.TextContainer.EndChange();
            } 
        }
 
        #endregion Private methods 

        //------------------------------------------------------ 
        //
        //  Private Properties
        //
        //----------------------------------------------------- 

        #region Private Properties 
 
        // A TextContainer covering the PasswordBox's inner content.
        private PasswordTextContainer TextContainer 
        {
            get
            {
                return _textContainer; 
            }
        } 
 
        /// 
        /// Text Selection (readonly) 
        /// 
        private ITextSelection Selection
        {
            get 
            {
                return _textEditor.Selection; 
            } 
        }
 

        #endregion Private Properties

        //------------------------------------------------------ 
        //
        //  Private Fields 
        // 
        //-----------------------------------------------------
 
        #region Private Fields

        // TextEditor working in this control instance
        private TextEditor _textEditor; 

        // Backing store for the control's content. 
        private PasswordTextContainer _textContainer; 

        // Encapsulated control that renders our TextContainer. 
        private TextBoxView _renderScope;

        // ScrollViewer
        private ScrollViewer _scrollViewer; 

        // Border 
        private Border _border; 

        // An element marked as ContentHostTemplateName which we assign our _renderScope as a child. 
        private FrameworkElement _passwordBoxContentHost;

        // Default size for the control.
        private const int _defaultWidth = 100; 
        private const int _defaultHeight = 20;
 
        // Part name used in the style. The class TemplatePartAttribute should use the same name 
        private const string ContentHostTemplateName = "PART_ContentHost";
 
        #endregion Private Fields

        #region DTypeThemeStyleKey
 
        // Returns the DependencyObjectType for the registered ThemeStyleKey's default
        // value. Controls will override this method to return approriate types. 
        internal override DependencyObjectType DTypeThemeStyleKey 
        {
            get { return _dType; } 
        }

        private static DependencyObjectType _dType;
 
        private NavigationService _navigationService;
        #endregion DTypeThemeStyleKey 
    } 

} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// File: PasswordBox.cs
//
// Copyright (C) Microsoft Corporation.  All rights reserved. 
//
// Description: The stock password control. 
// 
//---------------------------------------------------------------------------
 
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Globalization; 
using System.Security;
using System.Text; 
using System.Windows.Media; 
using System.Windows.Data;
using System.Windows.Documents; 
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Input;
using System.Windows.Navigation; 
using System.Windows.Shapes;
using System.Windows.Threading; 
using MS.Internal; 
using MS.Internal.KnownBoxes;
using System.Security.Permissions; 

#pragma warning disable 1634, 1691  // suppressing PreSharp warnings

namespace System.Windows.Controls 
{
    ///  
    /// The stock password control. 
    /// 
#if OLD_AUTOMATION 
    [Automation(AccessibilityControlType = "Edit")]
#endif
    [TemplatePart(Name = "PART_ContentHost", Type = typeof(FrameworkElement))]
    public sealed class PasswordBox : Control, ITextBoxViewHost 
#if OLD_AUTOMATION
        , IAutomationPatternProvider, IAutomationPropertyProvider 
#endif 
    {
        //----------------------------------------------------- 
        //
        //  Constructors
        //
        //----------------------------------------------------- 

        #region Constructors 
 
        /// 
        /// Static constructor for PasswordBox. 
        /// 
        static PasswordBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PasswordBox), new FrameworkPropertyMetadata(typeof(PasswordBox))); 
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(PasswordBox));
 
            // PasswordBox properties 
            // ------------------
            PasswordCharProperty.OverrideMetadata(typeof(PasswordBox), 
                    new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPasswordCharChanged)));

            // Declaree listener for Padding property
            Control.PaddingProperty.OverrideMetadata(typeof(PasswordBox), 
                new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPaddingChanged)));
 
            // Prevent journaling 
            NavigationService.NavigationServiceProperty.OverrideMetadata(typeof(PasswordBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnParentNavigationServiceChanged)));
 
            InputMethod.IsInputMethodEnabledProperty.OverrideMetadata(typeof(PasswordBox),
                    new FrameworkPropertyMetadata(
                            BooleanBoxes.FalseBox,
                            FrameworkPropertyMetadataOptions.Inherits, 
                            null,
                            // 
 
                            new CoerceValueCallback(ForceToFalse)));
        } 

        /// 
        /// Constructor.
        ///  
        public PasswordBox() : base()
        { 
            Initialize(); 
        }
 
        #endregion Constructors

        //------------------------------------------------------
        // 
        //  Public Methods
        // 
        //----------------------------------------------------- 

        #region Public Methods 

        /// 
        /// Replaces the current selection in the passwordbox with the contents
        /// of the Clipboard 
        /// 
        public void Paste() 
        { 
            RoutedCommand command = ApplicationCommands.Paste;
            command.Execute(null, this); 
        }

        /// 
        /// Select all text in the PasswordBox 
        /// 
        public void SelectAll() 
        { 
            Selection.Select(TextContainer.Start, TextContainer.End);
        } 

        /// 
        /// Clear all the content in the PasswordBox control.
        ///  
        public void Clear()
        { 
            this.Password = String.Empty; 
        }
 
        #endregion Public Methods

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

        #region Public Properties 

        /// 
        /// Contents of the PasswordBox.
        ///  
        /// 
        /// Use the SecurePassword property in place of this one when possible. 
        /// Doing so reduces the risk of revealing content that should be kept secret. 
        /// 
        ///  
        /// Critical - The getter elevates to unmanaged code and has unsafe code block.
        ///            The setter calls SetSecurePassword.
        ///
        /// PublicOK: Does not pass unsafe data to native code. 
        ///           Does not pass 2nd party SecureString to SetSecurePassword.
        /// 
        ///  
        [DefaultValue("")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public string Password
        {
            [SecurityCritical]
            get 
            {
                string password; 
 
                using (SecureString securePassword = this.SecurePassword)
                { 
                    IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(securePassword);

                    try
                    { 
                        unsafe
                        { 
                            password = new string((char*)ptr); 
                        }
                    } 
                    finally
                    {
                        System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
                    } 
                }
 
                return password; 
            }
 
            [SecurityCritical]
            set
            {
                if (value == null) 
                {
                    value = String.Empty; 
                } 

                using (SecureString securePassword = new SecureString()) 
                {
                    #pragma warning suppress 6506 // value is set to String.Empty if it was null.
                    for (int i = 0; i < value.Length; i++)
                    { 
                        securePassword.AppendChar(value[i]);
                    } 
 
                    SetSecurePassword(securePassword);
                } 
            }
        }

        ///  
        /// Contents of the PasswordBox.
        ///  
        ///  
        /// Reading the Password always returns a copy which may be safely
        /// Disposed. 
        ///
        /// Setting the value always stores a copy of the supplied value.
        /// 
        ///  
        /// Do not add public setter, see SetSecurePassword comments.
        ///  
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public SecureString SecurePassword
        { 
            get
            {
                return this.TextContainer.GetPasswordCopy();
            } 
        }
 
        ///  
        /// The DependencyID for the PasswordChar property.
        /// Default Value:     '*' 
        /// 
        public static readonly DependencyProperty PasswordCharProperty =
                DependencyProperty.RegisterAttached(
                        "PasswordChar", // Property name 
                        typeof(char), // Property type
                        typeof(PasswordBox), // Property owner 
                        new FrameworkPropertyMetadata('*')); // Flags 

        ///  
        /// Character to display instead of the actual password.
        /// 
        public char PasswordChar
        { 
            get { return (char) GetValue(PasswordCharProperty); }
            set { SetValue(PasswordCharProperty, value); } 
        } 

        ///  
        /// The limit number of characters that the PasswordBox or other editable controls can contain.
        /// if it is 0, means no-limitation.
        /// User can set this value for some simple single line PasswordBox to restrict the text number.
        /// By default it is 0. 
        /// 
        ///  
        /// When this property is set to zero, the maximum length of the text that can be entered 
        /// in the control is limited only by available memory. You can use this property to restrict
        /// the length of text entered in the control for values such as postal codes and telephone numbers. 
        /// You can also use this property to restrict the length of text entered when the data is to be entered
        /// in a database.
        /// You can limit the text entered into the control to the maximum length of the corresponding field in the database.
        /// Note:   In code, you can set the value of the Text property to a value that is larger than 
        /// the value specified by the MaxLength property.
        /// This property only affects text entered into the control at runtime. 
        ///  
        public static readonly DependencyProperty MaxLengthProperty =
                TextBox.MaxLengthProperty.AddOwner(typeof(PasswordBox)); 


        /// 
        /// Maximum number of characters the PasswordBox can accept 
        /// 
        [DefaultValue((int)0)] 
        public int MaxLength 
        {
            get { return (int) GetValue(MaxLengthProperty); } 
            set { SetValue(MaxLengthProperty, value); }
        }

        #endregion Public Properties 

        //----------------------------------------------------- 
        // 
        //  Public Events
        // 
        //------------------------------------------------------

        #region Public Events
 
        /// 
        /// Event for "Text has changed" 
        ///  
        /// 
        /// Unlike most RoutedEvents on Controls, PasswordChangedEvent does not 
        /// have a matching protected virtual OnPasswordChanged method --
        /// because PasswordBox is sealed.
        /// 
        public static readonly RoutedEvent PasswordChangedEvent = EventManager.RegisterRoutedEvent( 
            "PasswordChanged", // Event name
            RoutingStrategy.Bubble, // 
            typeof(RoutedEventHandler), // 
            typeof(PasswordBox)); //
 
        /// 
        /// Event fired from this text box when its inner content
        /// has been changed.
        ///  
        /// 
        /// It is redirected from inner TextContainer.Changed event. 
        ///  
        public event RoutedEventHandler PasswordChanged
        { 
            add
            {
                AddHandler(PasswordChangedEvent, value);
            } 

            remove 
            { 
                RemoveHandler(PasswordChangedEvent, value);
            } 
        }

        #endregion Public Events
 
        //-----------------------------------------------------
        // 
        //  Protected Methods 
        //
        //----------------------------------------------------- 

        #region Protected Methods

        ///  
        /// Creates AutomationPeer ()
        ///  
        protected override AutomationPeer OnCreateAutomationPeer() 
        {
            return new PasswordBoxAutomationPeer(this); 
        }

        /// 
        /// Called when the Template's tree has been generated 
        /// 
        public override void OnApplyTemplate() 
        { 
            base.OnApplyTemplate();
            AttachToVisualTree(); 
        }

        /// 
        /// Template has changed 
        /// 
        ///  
        ///  
        /// 
        ///  
        protected override void OnTemplateChanged(ControlTemplate oldTemplate, ControlTemplate newTemplate)
        {
            base.OnTemplateChanged(oldTemplate, newTemplate);
 
            if (oldTemplate!=null && newTemplate!= null && oldTemplate.VisualTree != newTemplate.VisualTree)
            { 
                DetachFromVisualTree(); 
            }
        } 

        ///
        /// 
        /// 
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        { 
            //  always call base.OnPropertyChanged, otherwise Property Engine will not work. 
            base.OnPropertyChanged(e);
 
            if (this.RenderScope != null)
            {
                FrameworkPropertyMetadata fmetadata = e.Property.GetMetadata(typeof(PasswordBox)) as FrameworkPropertyMetadata;
                if (fmetadata != null) 
                {
                    if (e.IsAValueChange || e.IsASubPropertyChange) 
                    { 
                        if (fmetadata.AffectsMeasure || fmetadata.AffectsArrange ||
                            fmetadata.AffectsParentMeasure || fmetadata.AffectsParentArrange || 
                            e.Property == Control.HorizontalContentAlignmentProperty || e.Property == Control.VerticalContentAlignmentProperty)
                        {
                            ((TextBoxView)this.RenderScope).Remeasure();
                        } 
                        else if (fmetadata.AffectsRender &&
                                (e.IsAValueChange || !fmetadata.SubPropertiesDoNotAffectRender)) 
                        { 
                            ((TextBoxView)this.RenderScope).Rerender();
                        } 
                    }
                }
            }
        } 

        ///  
        ///     Virtual method reporting a key was pressed 
        /// 
        protected override void OnKeyDown(KeyEventArgs e) 
        {
            base.OnKeyDown(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnKeyDown(e); 
        }

        /// 
        ///     Virtual method reporting a key was released 
        /// 
        protected override void OnKeyUp(KeyEventArgs e) 
        { 
            base.OnKeyUp(e);
 
            if (e.Handled)
            {
                return;
            } 

            _textEditor.OnKeyUp(e); 
        } 

        ///  
        ///     Virtual method reporting text composition
        /// 
        protected override void OnTextInput(TextCompositionEventArgs e)
        { 
            base.OnTextInput(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnTextInput(e);
        } 

        ///  
        ///     Virtual method reporting the mouse button was pressed 
        /// 
        protected override void OnMouseDown(MouseButtonEventArgs e) 
        {
            base.OnMouseDown(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnMouseDown(e); 
        }

        /// 
        ///     Virtual method reporting a mouse move 
        /// 
        protected override void OnMouseMove(MouseEventArgs e) 
        { 
            base.OnMouseMove(e);
 
            if (e.Handled)
            {
                return;
            } 

            _textEditor.OnMouseMove(e); 
        } 

        ///  
        ///     Virtual method reporting the mouse button was released
        /// 
        protected override void OnMouseUp(MouseButtonEventArgs e)
        { 
            base.OnMouseUp(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnMouseUp(e);
        } 

        ///  
        ///     Virtual method reporting the cursor to display was requested 
        /// 
        protected override void OnQueryCursor(QueryCursorEventArgs e) 
        {
            base.OnQueryCursor(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnQueryCursor(e); 
        }

        /// 
        ///     Virtual method reporting the query continue drag is going to happen 
        /// 
        protected override void OnQueryContinueDrag(QueryContinueDragEventArgs e) 
        { 
            base.OnQueryContinueDrag(e);
 
            if (e.Handled)
            {
                return;
            } 

            _textEditor.OnQueryContinueDrag(e); 
        } 

        ///  
        ///     Virtual method reporting the give feedback is going to happen
        /// 
        protected override void OnGiveFeedback(GiveFeedbackEventArgs e)
        { 
            base.OnGiveFeedback(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnGiveFeedback(e);
        } 

        ///  
        ///     Virtual method reporting the drag enter is going to happen 
        /// 
        protected override void OnDragEnter(DragEventArgs e) 
        {
            base.OnDragEnter(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnDragEnter(e); 
        }

        /// 
        ///     Virtual method reporting the drag over is going to happen 
        /// 
        protected override void OnDragOver(DragEventArgs e) 
        { 
            base.OnDragOver(e);
 
            if (e.Handled)
            {
                return;
            } 

            _textEditor.OnDragOver(e); 
        } 

        ///  
        ///     Virtual method reporting the drag leave is going to happen
        /// 
        protected override void OnDragLeave(DragEventArgs e)
        { 
            base.OnDragLeave(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnDragLeave(e);
        } 

        ///  
        ///     Virtual method reporting the drag enter is going to happen 
        /// 
        protected override void OnDrop(DragEventArgs e) 
        {
            base.OnDrop(e);

            if (e.Handled) 
            {
                return; 
            } 

            _textEditor.OnDrop(e); 
        }

// Disable CS0688: Method has link demand, but overrides method without link demand.
// In this case, we do not trust the input ContextMenuEventArgs (which may have its 
// UserInitiated bit set), so we do not tolerate this method being called in
// partial trust by a derived class.  However, it is perfectly reasonable for a 
// derived class in partial trust to override this method and bring up a custom menu 
// without any clipboard related items.
#pragma warning disable 688 
        /// 
        ///     Called when ContextMenuOpening is raised on this element.
        /// 
        /// Event arguments 
        /// 
        /// Critical - accepts a parameter which may be used to set the userInitiated 
        ///             bit on a command, which is used for security purposes later. 
        /// Public OK - link demanded.
        ///  
        [SecurityCritical]
        [UIPermissionAttribute(SecurityAction.LinkDemand, Clipboard = UIPermissionClipboard.AllClipboard)]
        protected override void OnContextMenuOpening(ContextMenuEventArgs e)
        { 
            base.OnContextMenuOpening(e);
 
            if (e.Handled) 
            {
                return; 
            }

            _textEditor.OnContextMenuOpening(e);
        } 
#pragma warning restore 688
 
        ///  
        ///     Virtual method reporting that the keyboard is focused on this element
        ///  
        protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            base.OnGotKeyboardFocus(e);
 
            if (e.Handled)
            { 
                return; 
            }
 
            _textEditor.OnGotKeyboardFocus(e);
        }

        ///  
        ///     Virtual method reporting that the keyboard is no longer focusekeyboard is no longer focuseed
        ///  
        protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e) 
        {
            base.OnLostKeyboardFocus(e); 

            if (e.Handled)
            {
                return; 
            }
 
            _textEditor.OnLostKeyboardFocus(e); 
        }
 
        /// 
        ///     This method is invoked when the IsFocused property changes to false
        /// 
        /// RoutedEventArgs 
        protected override void OnLostFocus(RoutedEventArgs e)
        { 
            base.OnLostFocus(e); 

            if (e.Handled) 
            {
                return;
            }
 
            _textEditor.OnLostFocus(e);
        } 
 
        #endregion Protected Methods
 
        //-----------------------------------------------------
        //
        //  Internal Properties
        // 
        //------------------------------------------------------
 
        #region Internal Properties 

        ///  
        /// readonly access to internal content control
        /// 
        internal FrameworkElement RenderScope
        { 
            get
            { 
                return _renderScope; 
            }
        } 

        internal ScrollViewer ScrollViewer
        {
            get 
            {
                if (_scrollViewer == null) 
                { 
                    if (_textEditor != null)
                    { 
                        _scrollViewer = _textEditor._Scroller as ScrollViewer;
                    }
                }
                return _scrollViewer; 
            }
        } 
 
        // ITextContainer holding the Control content.
        ITextContainer ITextBoxViewHost.TextContainer 
        {
            get
            {
                return this.TextContainer; 
            }
        } 
 
        // Set true when typography property values are all default values.
        bool ITextBoxViewHost.IsTypographyDefaultValue 
        {
            get
            {
                return true; 
            }
        } 
 
        #endregion Internal Properties
 
        //-----------------------------------------------------
        //
        //  Private Methods
        // 
        //------------------------------------------------------
 
        #region Private Methods 

        // Worker for the ctors, initializes a new PasswordBox instance. 
        private void Initialize()
        {
            // Register static editing command handlers.
            // This only has an effect that first time we make the call. 
            // We don't use the static ctor because there are cases
            // where another control will want to alias our properties 
            // but doesn't need this overhead. 
            TextEditor.RegisterCommandHandlers(typeof(PasswordBox), /*acceptsRichContent:*/false, /*readOnly*/false, /*registerEventListeners*/false);
 
            // Create TextContainer
            InitializeTextContainer(new PasswordTextContainer(this));

            // PasswordBox only accepts plain text, so change TextEditor's default to that. 
            _textEditor.AcceptsRichContent = false;
 
            // PasswordBox does not accetps tabs. 
            _textEditor.AcceptsTab = false;
        } 

        // Attaches this control to a new TextContainer.
        private void InitializeTextContainer(PasswordTextContainer textContainer)
        { 
            Invariant.Assert(textContainer != null);
 
            // Uninitialize previous TextEditor 
            if (_textContainer != null)
            { 
                Invariant.Assert(_textEditor != null);
                Invariant.Assert(_textEditor.TextContainer == _textContainer);

                // Detach existing editor from VisualTree 
                DetachFromVisualTree();
 
                // Discard TextEditor - must release text container 
                _textEditor.OnDetach();
            } 

            // Save text container
            _textContainer = textContainer;
 
            //
            ((ITextContainer)_textContainer).Changed += new TextContainerChangedEventHandler(OnTextContainerChanged); 
 
            // Create a text editor, initialize undo manager for it, and link it to text container
            _textEditor = new TextEditor(_textContainer, this, true); 
        }

        // Disable IME input unconditionally.  We really can't support
        // IMEs in this control, because PasswordTextContainer doesn't 
        // round-trip content, which breaks the cicero contract.
        // Additionally, from a UI standpoint, we don't want to break 
        // user expectations by allowing IME input.  IMEs do cool things 
        // like learn from user corrections, so the same keystroke sequence
        // might produce different text over time. 
        private static object ForceToFalse(DependencyObject d, object value)
        {
            return BooleanBoxes.FalseBox;
        } 

        ///  
        /// Callback for changes to the PasswordChar property. 
        /// 
        private static void OnPasswordCharChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            PasswordBox passwordBox = (PasswordBox)d;

            // Force a layout refresh to display the new char. 
            if (passwordBox._renderScope != null)
            { 
                passwordBox._renderScope.InvalidateMeasure(); 
            }
        } 

        /// 
        /// Handler for text array change notifications.
        ///  
        /// 
        /// sender 
        ///  
        /// 
        /// event args 
        /// 
        private void OnTextContainerChanged(object sender, TextContainerChangedEventArgs e)
        {
            // If only properties on the text changed, don't fire a content change event. 
            // This can happen even in a plain text TextBox if we switch logical trees.
            if (!e.HasContentAddedOrRemoved) 
            { 
                return;
            } 

            RaiseEvent(new RoutedEventArgs(PasswordChangedEvent));
        }
 
        /// 
        /// Walk the visual tree until we find a Text control with IsPasswordBoxContent == true 
        /// and a ScrollViewer 
        /// 
        private void SetRenderScopeToContentHost(TextBoxView renderScope) 
        {
            // Clear the content host from previous render scope (if any)
            ClearContentHost();
 
            // Find ContentHostTemplateName in the style
            _passwordBoxContentHost = GetTemplateChild(ContentHostTemplateName) as FrameworkElement; 
 
            // Note that we allow ContentHostTemplateName to be optional.
            // This simplifies toolability of our control styling. 
            // When the ContentHostTemplateName is not found or incorrect
            // PasswordBox goes into disabled state, but does not throw.

            // Add renderScope as a child of ContentHostTemplateName 
            _renderScope = renderScope;
            if (_passwordBoxContentHost is ScrollViewer) 
            { 
                ScrollViewer scrollViewer = (ScrollViewer)_passwordBoxContentHost;
                if (scrollViewer.Content != null) 
                {
                    throw new NotSupportedException(SR.Get(SRID.TextBoxScrollViewerMarkedAsTextBoxContentMustHaveNoContent));
                }
                else 
                {
                    scrollViewer.Content = _renderScope; 
                } 
            }
            else if (_passwordBoxContentHost is Decorator) 
            {
                Decorator decorator = (Decorator)_passwordBoxContentHost;
                if (decorator.Child != null)
                { 
                    throw new NotSupportedException(SR.Get(SRID.TextBoxDecoratorMarkedAsTextBoxContentMustHaveNoContent));
                } 
                else 
                {
                    decorator.Child = _renderScope; // this may replace old render scope in case of upgrade scenario in TextBox 
                }
            }
            else
            { 
                // When we implement TextContainer setting via TextView interface
                // all text containing element will become allowed here. 
                _renderScope = null; 

                // Explicitly not throwing an exception here when content host = null 
                // -- designers need us to support no content scenarios
                if (_passwordBoxContentHost != null)
                {
                    _passwordBoxContentHost = null; 
                    //
                    throw new NotSupportedException(SR.Get(SRID.PasswordBoxInvalidTextContainer)); 
                } 
            }
 
            // Attach render scope to TextEditor
            InitializeRenderScope();

            FrameworkElement element = _renderScope; 
            while (element != this && element != null)  // checking both just to be safe
            { 
                if (element is Border) 
                {
                    _border = (Border)element; 
                }
                element = element.Parent as FrameworkElement;
            }
        } 

        private void ClearContentHost() 
        { 
            // Detach render scope from TextEditor
            UninitializeRenderScope(); 

            // Render scope has been created by us,
            // so we need to extract if from visual tree.
            if (_passwordBoxContentHost is ScrollViewer) 
            {
                ((ScrollViewer)_passwordBoxContentHost).Content = null; 
            } 
            else if (_passwordBoxContentHost is Decorator)
            { 
                ((Decorator)_passwordBoxContentHost).Child = null;
            }
            else
            { 
                Invariant.Assert(_passwordBoxContentHost == null, "_passwordBoxContentHost must be null here");
            } 
 
            _passwordBoxContentHost = null;
        } 

        // Initializes a new render scope.
        private void InitializeRenderScope()
        { 
            if (_renderScope == null)
            { 
                return; 
            }
 
            // Attach the renderScope to TextEditor as its ITextView member.
            ITextView textview = TextEditor.GetTextView(_renderScope);
            _textEditor.TextView = textview;
            this.TextContainer.TextView = textview; 

            if (this.ScrollViewer != null) 
            { 
                this.ScrollViewer.CanContentScroll = true;
            } 
        }

        // Uninitializes a render scope and clears this control's reference.
        private void UninitializeRenderScope() 
        {
            // Clear TextView property in TextEditor 
            _textEditor.TextView = null; 
        }
 
        // Resets the selection to the start of the content.
        // Called after non-TOM changes to the content, like
        // set_Text
        private void ResetSelection() 
        {
            Select(0, 0); 
 
            if (this.ScrollViewer != null)
            { 
                this.ScrollViewer.ScrollToHome();
            }
        }
 
        /// 
        /// Select the text in the given position and length. 
        ///  
        private void Select(int start, int length)
        { 
            ITextPointer selectionStart;
            ITextPointer selectionEnd;

            //             VerifyAccess(); 
            if (start < 0)
            { 
                throw new ArgumentOutOfRangeException("start", SR.Get(SRID.ParameterCannotBeNegative)); 
            }
 
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", SR.Get(SRID.ParameterCannotBeNegative));
            } 

            // Identify new selection start position 
            selectionStart = this.TextContainer.Start.CreatePointer(); 
            while (start-- > 0 && selectionStart.MoveToNextInsertionPosition(LogicalDirection.Forward))
            { 
            }

            // Identify new selection end position
            selectionEnd = selectionStart.CreatePointer(); 
            while (length-- > 0 && selectionEnd.MoveToNextInsertionPosition(LogicalDirection.Forward))
            { 
            } 

            Selection.Select(selectionStart, selectionEnd); 
        }

        /// 
        /// Callback for TextBox.Padding property setting 
        /// 
        ///  
        /// TextBoxBase on which the property is changed 
        /// 
        /// event args 
        private static void OnPaddingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PasswordBox passwordBox = (PasswordBox)d;
 
            if (passwordBox.ScrollViewer != null)
            { 
                // translate this change into inner property set on ScrollViewer 
                object padding = passwordBox.GetValue(Control.PaddingProperty);
                if (padding is Thickness) 
                {
                    passwordBox.ScrollViewer.Padding = (Thickness)padding;
                }
                else 
                {
                    passwordBox.ScrollViewer.ClearValue(Control.PaddingProperty); 
                } 
            }
        } 

        // Set up listener for Navigating event
        private static void OnParentNavigationServiceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        { 
            PasswordBox passwordBox = (PasswordBox)o;
            NavigationService navService = NavigationService.GetNavigationService(o); 
            if (passwordBox._navigationService != null) 
            {
                passwordBox._navigationService.Navigating -= new NavigatingCancelEventHandler(passwordBox.OnNavigating); 
            }
            if (navService != null)
            {
                navService.Navigating += new NavigatingCancelEventHandler(passwordBox.OnNavigating); 
                passwordBox._navigationService = navService;
            } 
            else 
            {
                passwordBox._navigationService = null; 
            }
        }

        // Clear password on navigation to prevent journaling. 
        private void OnNavigating(Object sender, NavigatingCancelEventArgs e)
        { 
            this.Password = String.Empty; 
        }
 
        /// 
        /// Detaches the editor from old visual tree and attaches it to a new one
        /// 
        private void AttachToVisualTree() 
        {
            DetachFromVisualTree(); 
 
            // Walk the visual tree to find our Text element
            SetRenderScopeToContentHost(new TextBoxView(this)); 

            // Attach scroll handler to the new scroll viewer
            // Note that this.ScrollViewer will walk the tree from current TextEditor's render scope up to its ui scope.
            if (this.ScrollViewer != null) 
            {
                this.ScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden; 
                this.ScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled; 
                this.ScrollViewer.Focusable = false;
 
                if (this.ScrollViewer.Background == null)
                {
                    // prevent hit-testing through padding
                    this.ScrollViewer.Background = Brushes.Transparent; 
                }
                OnPaddingChanged(this, new DependencyPropertyChangedEventArgs()); 
            } 

            // Set border properties 
            if (_border != null)
            {
                _border.Style = null;
            } 
        }
 
        ///  
        /// Clear our layout-specific data, and detach our current renderScope from our text editor.
        ///  
        private void DetachFromVisualTree()
        {
            if (_textEditor != null)
            { 
                _textEditor.Selection.DetachFromVisualTree();
            } 
 
            // Invalidate our cached copy of scroll viewer.
            _scrollViewer = null; 
            _border = null;

            ClearContentHost();
        } 

        ///  
        /// Sets the content of the control. 
        /// 
        ///  
        /// Critical - This method indirectly reveals value's SecureString content.
        ///
        /// This method must never be passed a publicly supplied SecureString as long as we expose
        /// a plain text get_Password property. 
        ///
        /// 1. Attacker sets SecureString value it does not have permission to read. 
        /// 2. Attacker reads Password property. 
        /// --> attacker has ----ed open a SecureString without UnmanagedCode permission.
        ///  
        [SecurityCritical]
        private void SetSecurePassword(SecureString value)
        {
            this.TextContainer.BeginChange(); 
            try
            { 
                this.TextContainer.SetPassword(value); 
                this.ResetSelection();
            } 
            finally
            {
                this.TextContainer.EndChange();
            } 
        }
 
        #endregion Private methods 

        //------------------------------------------------------ 
        //
        //  Private Properties
        //
        //----------------------------------------------------- 

        #region Private Properties 
 
        // A TextContainer covering the PasswordBox's inner content.
        private PasswordTextContainer TextContainer 
        {
            get
            {
                return _textContainer; 
            }
        } 
 
        /// 
        /// Text Selection (readonly) 
        /// 
        private ITextSelection Selection
        {
            get 
            {
                return _textEditor.Selection; 
            } 
        }
 

        #endregion Private Properties

        //------------------------------------------------------ 
        //
        //  Private Fields 
        // 
        //-----------------------------------------------------
 
        #region Private Fields

        // TextEditor working in this control instance
        private TextEditor _textEditor; 

        // Backing store for the control's content. 
        private PasswordTextContainer _textContainer; 

        // Encapsulated control that renders our TextContainer. 
        private TextBoxView _renderScope;

        // ScrollViewer
        private ScrollViewer _scrollViewer; 

        // Border 
        private Border _border; 

        // An element marked as ContentHostTemplateName which we assign our _renderScope as a child. 
        private FrameworkElement _passwordBoxContentHost;

        // Default size for the control.
        private const int _defaultWidth = 100; 
        private const int _defaultHeight = 20;
 
        // Part name used in the style. The class TemplatePartAttribute should use the same name 
        private const string ContentHostTemplateName = "PART_ContentHost";
 
        #endregion Private Fields

        #region DTypeThemeStyleKey
 
        // Returns the DependencyObjectType for the registered ThemeStyleKey's default
        // value. Controls will override this method to return approriate types. 
        internal override DependencyObjectType DTypeThemeStyleKey 
        {
            get { return _dType; } 
        }

        private static DependencyObjectType _dType;
 
        private NavigationService _navigationService;
        #endregion DTypeThemeStyleKey 
    } 

} 

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