locked
DatagridView column format for passwords RRS feed

  • Question

  • How can I change the column format from an Datagridview to display the password char (same as UseSystemPasswordChar in a TextBox)?

    I have a column of type DataGridViewTextBoxColumn, but there isn't this property.
    Tuesday, May 3, 2005 9:18 AM

Answers

  • Handle the EditingControlShowing event and then cast the editing control to a TextBox and manually set the UseSystemPasswordChar to true:



    TextBox t = e.Control as TextBox;
    if (t != null)
    {
        t.UseSystemPasswordChar = true;
    }


     

    -mark
    Program Manager
    Microsoft
    This post is provided "as-is"

    Thursday, May 5, 2005 10:06 PM
  • Source:  http://www.codeproject.com/cs/miscctrl/passwordbox.asp?print=true



    using System;
    using
    System.ComponentModel;
    using
    System.Drawing;
    using
    System.Windows.Forms;
    using
    System.Diagnostics;

    namespace PasswordBox
    {
    public class PasswordBox : System.Windows.Forms.TextBox
     {
      #region *** Constants from WinUser.h ***


      // The .NET Frasmwork adds this style bit to the TextBox.
      private const int WS_MAXIMIZEBOX = 0x00010000;


      // This is the style flag that makes a text box a real password box. 
      private const int ES_PASSWORD    = 0x0020; 

      private const int ES_AUTOHSCROLL = 0x0080;

      /// <summary>
      /// Used in ProcessKeyMessage
      /// </summary>
      private const int WM_CHAR = 0x0102;

      #endregion


      // An internal buffer used to hold the text of the
      // password being entered
      // We don't hold the password in the .Text member of TextBox
      // since it used in the window text.
      private System.Text.StringBuilder _internalBuffer
       = new System.Text.StringBuilder();


      // Default constructor of PasswordBox
      public PasswordBox()
      {
       // No further initialization required 
      }


      // Multiline password aren't allowed wo be just hide the implementation
      private new bool Multiline
      {
       get { return false; }
      }


      // Sets/gets the actual password entered
      [Localizable(false)]
      public override string Text
      {
       get { return _internalBuffer.ToString(); }
       set
       {   
         //assign base.Text first
        base.Text = ((value == null) ? value : new String(' ', value.Length));

        // Not fill the buffer with the new value
        _internalBuffer = new System.Text.StringBuilder(value, MaxLength);

        Debug.Assert(base.TextLength == _internalBuffer.Length);
       }
      }


      // Override. TextLength returns the length of the internal buffer.
      // TextLength is overridden so that checks can be made
      // during debugging to ensure the lengths of base.Text
      // and _internalsBuffer.Lengh are equal.
      public override int TextLength
      {
       get
       {
        Debug.Assert(base.TextLength == _internalBuffer.Length,
         "base.TextLength != _internalBuffer.Length");

        return _internalBuffer.Length;
       }
      }


      // Overridden. See Control.CreateParams
      // This is how we get PasswordBox to show the black dots instead
      // of PasswordChar on systems that support it.

      protected override CreateParams CreateParams
      {
       get
       {
        CreateParams cp = base.CreateParams;
        if ( !DesignMode )
        {
         // Even tho the style is added here, it seems
         // to be removed somewhere. What makes things
         // stranger is, setting this style does have
         // an effect, and does cause the TextBox to
         // work as expected.
         cp.Style |= ES_PASSWORD;
        }
        return cp;

       }
      }

      protected override void Dispose( bool disposing )
      {
       if( disposing )
       {
       }
       base.Dispose( disposing );
      }


      // Overridden. Processes a command key.
      // A Message, passed by reference, that represents the window message to process.
      // One of the Keys values that represents the key to process.
      // true if the character was processed by the control; otherwise, false
      protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
      {
       
       if( (keyData == (Keys.Control | Keys.V))
        || (keyData == (Keys.Shift | Keys.Insert)) )
       {
        //Do the paste if appropriate
        IDataObject data = Clipboard.GetDataObject();
        if ( data.GetDataPresent(DataFormats.Text) )
        {
         ReplaceSelection((string)data.GetData(DataFormats.Text));
         return true;
        }
       }
       else if ( keyData == (Keys.Control | Keys.C)
        || keyData == (Keys.Control | Keys.Insert)
        || keyData == (Keys.Shift | Keys.Delete) )
       {
        // Eat the keystroke
        return true;
       }
       else if ( keyData == Keys.Delete )
       {
        // Process the delete key at the current position
        DeleteChar();
       }

       return base.ProcessCmdKey(ref msg, keyData); 
      }


      // Overridden. Processes a keyboard message. See online documentation
      // A Message, passed by reference, that represents the window message to process.
      // true if the message was processed by the control; otherwise, false.
      protected override bool ProcessKeyMessage(ref Message m)
      {
       bool result = true;

       switch ( m.Msg )
       {
        // This should be the only one we have to handle
        case WM_CHAR: 
        {
         switch ((Keys)(int)m.WParam)
         {
          case Keys.Back:
           ProcessChar('\b');
           break;

           /*
            * If there are any problems you may
            * want to add these as needed.
            *************************************
            * case Keys.LineFeed:
            *  break;
            * case Keys.Escape:
            *  break; 
            *
            * case Keys.Tab:
            *  break; 
            *
            * case Keys.Enter:
            * break; 
            *
            */

          default:
           char c = (char)m.WParam;
           if ( !char.IsControl(c) )
           {
            m.WParam = (IntPtr)' ';
            ProcessChar(c);
           }       
           break;
         }
         break;
        }

        default:     
         break;

       }
       // On with default handling
       result = ProcessKeyEventArgs(ref m);

       return result;
      }

      #region ** Internal Helper Methods **

      /// <summary>
      /// Deletes the character(s) at the current position
      /// </summary>
      private void DeleteChar()
      {
       int posStart  = SelectionStart;
       int posLength = SelectionLength;

       if ( posLength > 0 )
       {
        _internalBuffer.Remove(posStart, posLength);
       }
       else
       {
        if ( posStart < (_internalBuffer.Length -1) )
        {
         _internalBuffer.Remove(posStart, 1);
        }
       }
      }

      /// <summary>
      /// Replaces the current selection with string s
      /// </summary>
      /// <param name="s">The string to use as the replacement.</param>
      private void ReplaceSelection(string s)
      {
       int posStart  = SelectionStart;
       int posLength = SelectionLength;

       if ( posLength > 0 )
       {
        _internalBuffer.Remove(posStart, posLength);
       }
       Text = _internalBuffer.Insert(posStart, s).ToString();
       Select(posStart +s.Length, 0);
      }

      /// <summary>
      /// Process a character and ake the appropriate action.
      /// </summary>
      /// <param name="c">
      /// The character to process. If char c is not '\b' then char c
      /// is inserted at the current position.
      /// </param>
      private void ProcessChar(char c)
      {
       int posStart  = SelectionStart;
       int posLength = SelectionLength;

       if ( posLength > 0 )
       {
        _internalBuffer.Remove(posStart, posLength);    
       }
       else
       {
        if ( c == '\b' )
        {
         if ( posStart > 0 )
         {
          _internalBuffer.Remove(posStart -1, 1);
         }
         return;
        }
       }
       _internalBuffer.Insert(posStart, c);
      }
      #endregion


     }
    }


     

    Friday, June 3, 2005 3:01 PM

All replies

  • Handle the EditingControlShowing event and then cast the editing control to a TextBox and manually set the UseSystemPasswordChar to true:



    TextBox t = e.Control as TextBox;
    if (t != null)
    {
        t.UseSystemPasswordChar = true;
    }


     

    -mark
    Program Manager
    Microsoft
    This post is provided "as-is"

    Thursday, May 5, 2005 10:06 PM
  • Thanks for replay, but my datagridview is readonly, and I need display the * character in the password column when they are displayed (not when I'm editing the cell).
    Friday, May 6, 2005 6:28 AM
  • If it is read-only, why display passwords at all?

    I can see no reason to show how many characters are in password (by replacing chars with *), it only makes it less secure.
    Tuesday, May 10, 2005 1:05 PM
  • I want display only * with the same length for all fields. It's for inform users that there is a password.
    Friday, May 27, 2005 11:13 AM
  • Source:  http://www.codeproject.com/cs/miscctrl/passwordbox.asp?print=true



    using System;
    using
    System.ComponentModel;
    using
    System.Drawing;
    using
    System.Windows.Forms;
    using
    System.Diagnostics;

    namespace PasswordBox
    {
    public class PasswordBox : System.Windows.Forms.TextBox
     {
      #region *** Constants from WinUser.h ***


      // The .NET Frasmwork adds this style bit to the TextBox.
      private const int WS_MAXIMIZEBOX = 0x00010000;


      // This is the style flag that makes a text box a real password box. 
      private const int ES_PASSWORD    = 0x0020; 

      private const int ES_AUTOHSCROLL = 0x0080;

      /// <summary>
      /// Used in ProcessKeyMessage
      /// </summary>
      private const int WM_CHAR = 0x0102;

      #endregion


      // An internal buffer used to hold the text of the
      // password being entered
      // We don't hold the password in the .Text member of TextBox
      // since it used in the window text.
      private System.Text.StringBuilder _internalBuffer
       = new System.Text.StringBuilder();


      // Default constructor of PasswordBox
      public PasswordBox()
      {
       // No further initialization required 
      }


      // Multiline password aren't allowed wo be just hide the implementation
      private new bool Multiline
      {
       get { return false; }
      }


      // Sets/gets the actual password entered
      [Localizable(false)]
      public override string Text
      {
       get { return _internalBuffer.ToString(); }
       set
       {   
         //assign base.Text first
        base.Text = ((value == null) ? value : new String(' ', value.Length));

        // Not fill the buffer with the new value
        _internalBuffer = new System.Text.StringBuilder(value, MaxLength);

        Debug.Assert(base.TextLength == _internalBuffer.Length);
       }
      }


      // Override. TextLength returns the length of the internal buffer.
      // TextLength is overridden so that checks can be made
      // during debugging to ensure the lengths of base.Text
      // and _internalsBuffer.Lengh are equal.
      public override int TextLength
      {
       get
       {
        Debug.Assert(base.TextLength == _internalBuffer.Length,
         "base.TextLength != _internalBuffer.Length");

        return _internalBuffer.Length;
       }
      }


      // Overridden. See Control.CreateParams
      // This is how we get PasswordBox to show the black dots instead
      // of PasswordChar on systems that support it.

      protected override CreateParams CreateParams
      {
       get
       {
        CreateParams cp = base.CreateParams;
        if ( !DesignMode )
        {
         // Even tho the style is added here, it seems
         // to be removed somewhere. What makes things
         // stranger is, setting this style does have
         // an effect, and does cause the TextBox to
         // work as expected.
         cp.Style |= ES_PASSWORD;
        }
        return cp;

       }
      }

      protected override void Dispose( bool disposing )
      {
       if( disposing )
       {
       }
       base.Dispose( disposing );
      }


      // Overridden. Processes a command key.
      // A Message, passed by reference, that represents the window message to process.
      // One of the Keys values that represents the key to process.
      // true if the character was processed by the control; otherwise, false
      protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
      {
       
       if( (keyData == (Keys.Control | Keys.V))
        || (keyData == (Keys.Shift | Keys.Insert)) )
       {
        //Do the paste if appropriate
        IDataObject data = Clipboard.GetDataObject();
        if ( data.GetDataPresent(DataFormats.Text) )
        {
         ReplaceSelection((string)data.GetData(DataFormats.Text));
         return true;
        }
       }
       else if ( keyData == (Keys.Control | Keys.C)
        || keyData == (Keys.Control | Keys.Insert)
        || keyData == (Keys.Shift | Keys.Delete) )
       {
        // Eat the keystroke
        return true;
       }
       else if ( keyData == Keys.Delete )
       {
        // Process the delete key at the current position
        DeleteChar();
       }

       return base.ProcessCmdKey(ref msg, keyData); 
      }


      // Overridden. Processes a keyboard message. See online documentation
      // A Message, passed by reference, that represents the window message to process.
      // true if the message was processed by the control; otherwise, false.
      protected override bool ProcessKeyMessage(ref Message m)
      {
       bool result = true;

       switch ( m.Msg )
       {
        // This should be the only one we have to handle
        case WM_CHAR: 
        {
         switch ((Keys)(int)m.WParam)
         {
          case Keys.Back:
           ProcessChar('\b');
           break;

           /*
            * If there are any problems you may
            * want to add these as needed.
            *************************************
            * case Keys.LineFeed:
            *  break;
            * case Keys.Escape:
            *  break; 
            *
            * case Keys.Tab:
            *  break; 
            *
            * case Keys.Enter:
            * break; 
            *
            */

          default:
           char c = (char)m.WParam;
           if ( !char.IsControl(c) )
           {
            m.WParam = (IntPtr)' ';
            ProcessChar(c);
           }       
           break;
         }
         break;
        }

        default:     
         break;

       }
       // On with default handling
       result = ProcessKeyEventArgs(ref m);

       return result;
      }

      #region ** Internal Helper Methods **

      /// <summary>
      /// Deletes the character(s) at the current position
      /// </summary>
      private void DeleteChar()
      {
       int posStart  = SelectionStart;
       int posLength = SelectionLength;

       if ( posLength > 0 )
       {
        _internalBuffer.Remove(posStart, posLength);
       }
       else
       {
        if ( posStart < (_internalBuffer.Length -1) )
        {
         _internalBuffer.Remove(posStart, 1);
        }
       }
      }

      /// <summary>
      /// Replaces the current selection with string s
      /// </summary>
      /// <param name="s">The string to use as the replacement.</param>
      private void ReplaceSelection(string s)
      {
       int posStart  = SelectionStart;
       int posLength = SelectionLength;

       if ( posLength > 0 )
       {
        _internalBuffer.Remove(posStart, posLength);
       }
       Text = _internalBuffer.Insert(posStart, s).ToString();
       Select(posStart +s.Length, 0);
      }

      /// <summary>
      /// Process a character and ake the appropriate action.
      /// </summary>
      /// <param name="c">
      /// The character to process. If char c is not '\b' then char c
      /// is inserted at the current position.
      /// </param>
      private void ProcessChar(char c)
      {
       int posStart  = SelectionStart;
       int posLength = SelectionLength;

       if ( posLength > 0 )
       {
        _internalBuffer.Remove(posStart, posLength);    
       }
       else
       {
        if ( c == '\b' )
        {
         if ( posStart > 0 )
         {
          _internalBuffer.Remove(posStart -1, 1);
         }
         return;
        }
       }
       _internalBuffer.Insert(posStart, c);
      }
      #endregion


     }
    }


     

    Friday, June 3, 2005 3:01 PM
  •  

    Handle the CellFormatting event of the grid.

    If you are in the right column (password) show "*".

     

     

    Private Sub grid_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles grid.CellFormatting

      If (e.ColumnIndex <> -1 AndAlso grid.Columns(e.ColumnIndex).Name = "UserPassword") Then

        If (Not e.Value Is Nothing) Then

          e.Value = New String("*", e.Value.ToString().Length)

        End If

      End If

    End Sub

     

     

    Good luck,

    Tamir

    • Proposed as answer by cerx Wednesday, February 18, 2009 8:13 PM
    Monday, April 2, 2007 8:52 AM
  • Hi Mark,

     

    I am facing one issue. Once I tab Out from the cell whose chars are set to password, the text change back to normal text

    How to stop that

    Thanks

    Dharmbir
    Wednesday, May 30, 2007 7:59 AM
  • In addition to

    EditingControlShowing

     I have also added the following code in CellFormatting event

     

    void dgrdPasswords_CellFormatting(object sender, System.Windows.Forms.DataGridViewCellFormattingEventArgs e)

    {

    if (e.ColumnIndex > 0 && e.Value != null)

    {

    e.Value = new String('*', e.Value.ToString().Length);

    }

    }

     

    and it works...

     

    Thanks

    Jaya.

    • Proposed as answer by cerx Wednesday, February 18, 2009 8:13 PM
    Monday, June 11, 2007 2:58 PM
  •  

    Easy two metods:

     

    ' to edit password char

    Private Sub SetFormat(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles UsuariosDataGridView.CellFormatting

    Dim Nombre As String = UsuariosDataGridView.Columns(e.ColumnIndex).Name

    If (e.ColumnIndex <> -1 And Nombre = "DataGridViewTextBoxColumn4") Then

    If (Not e.Value Is Nothing) Then

    e.Value = New String("*", e.Value.ToString().Length)

    End If

    End If

    End Sub

     

    ' And

    ' to view password char

     

    Private Sub EditFormat(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles UsuariosDataGridView.EditingControlShowing

     

    If (CType(sender, DataGridView).CurrentCell.ColumnIndex = 4) Then

    CType(e.Control, TextBox).PasswordChar = "*"

    Else

    CType(e.Control, TextBox).PasswordChar = Char.MinValue

    End If

     

    End Sub

     

     

    note: the column index 4 it is the column to make password

    • Proposed as answer by cerx Wednesday, February 18, 2009 8:12 PM
    Friday, July 27, 2007 5:58 AM
  •  Anonymous561786 wrote:
     

    Handle the CellFormatting event of the grid.

    If you are in the right column (password) show "*".

     

     

    Private Sub grid_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles grid.CellFormatting

      If (e.ColumnIndex <> -1 AndAlso grid.Columns(e.ColumnIndex).Name = "UserPassword") Then

        If (Not e.Value Is Nothing) Then

          e.Value = New String("*", e.Value.ToString().Length)

        End If

      End If

    End Sub

     

     

    Good luck,

    Tamir

    Works great!  Thanks, Tamir.

    • Proposed as answer by cerx Wednesday, February 18, 2009 8:12 PM
    Sunday, September 16, 2007 11:24 PM
  • Hi there, I am trying to do a smiliar thing for 2 columns in a datagridview. How can determine that I want to do this for columns 4 and 5. There is no ColumnIndex property for e in the EditingControlShowing event.

     

    Thanks in advance

    Abdullah

     

    Thursday, August 21, 2008 12:56 PM
  • Jaya
    Thanks so much.  Simple and purpose-focused.  Exactly what I needed!
    Thursday, September 24, 2009 2:41 PM
  • You have to handle two events :

               

        private void grdServerDetails_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                if (grdServerDetails.CurrentCell.ColumnIndex == 3)
                {
                    TextBox tb = e.Control as TextBox;
                    if (tb != null)
                    {
                        tb.PasswordChar = '*';
                    }
                }

            }

       private void grdServerDetails_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
            {
                if (e.ColumnIndex == 3)
                {
                    if (e.Value != null)
                    {
                        e.Value = new string('*', e.Value.ToString().Length);
                    }
                }
            }

    Its as simple as this.

    It should work.


    EMCUBE

    Friday, December 14, 2012 7:09 AM

  • You have to handle two events :

               

        private void grdServerDetails_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                if (grdServerDetails.CurrentCell.ColumnIndex == 3)
                {
                    TextBox tb = e.Control as TextBox;
                    if (tb != null)
                    {
                        tb.PasswordChar = '*';
                    }
                }

            }

       private void grdServerDetails_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
            {
                if (e.ColumnIndex == 3)
                {
                    if (e.Value != null)
                    {
                        e.Value = new string('*', e.Value.ToString().Length);
                    }
                }
            }

    Its as simple as this.

    It should work.

    Pls mark this as answer. If it works for u.


    EMCUBE

    • Proposed as answer by Denny966 Monday, October 20, 2014 2:57 PM
    Friday, December 14, 2012 7:14 AM
  • Thank you, i used this method and work perfect in vb.net 2013
    Sunday, March 9, 2014 1:47 PM
  • thanks, works great

    yzzid

    Friday, August 15, 2014 9:50 PM
  • This works great, but how do you retrieve the actual string?
    Monday, October 20, 2014 2:57 PM