简体   繁体   中英

How to retrieve password from c# Winforms datagridview cell after masking while saving the data

I have used below codes to mask my password in datagridview and i am successfully doing it.

private void gvInstanceDetails_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
      if (e.ColumnIndex == 4)
      {
        if (e.Value != null)
        {
          gvInstanceDetails.Rows[e.RowIndex].Tag = e.Value;
          e.Value = new string('\u2022', e.Value.ToString().Length);
        }
      }
    }

    private void gvInstanceDetails_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {      
        TextBox t = e.Control as TextBox;
        if (t != null)
        {
          t.UseSystemPasswordChar = true;
        }      
    } 

Once I mask, I am unable to retrieve the value that is getting entered by user into the password field, if user is not deleting the entire text and re enter the password.

eg: - if password is like ***** and user replaces last two characters and enter 34 then while saving i am getting string as ***34.

Thanks

Quick Fix

The EditingControl uses FormattedValue of the cell for editing.

As a quick fix, in the EditingControlShowing handler set the Value of the CurrentCell as Text of the TextBox :

private void DataGridView1_EditingControlShowing(object sender,
    DataGridViewEditingControlShowingEventArgs e)
{
    if (dataGridView1.CurrentCell.ColumnIndex == 4)
    {
        var txt = (TextBox)e.Control;
        txt.Text = $"{dataGridView1.CurrentCell.Value}";
        txt.UseSystemPasswordChar = true;
    }
}

Better Option - Create DataGridViewPasswordColumn

As a better option, create a DataGridViewPasswordColumn which handles the logic for you:

public class DataGridViewPasswordColumn : DataGridViewTextBoxColumn
{
    public DataGridViewPasswordColumn()
    {
        this.CellTemplate = new DataGriViewPasswordCell();
    }
}
public class DataGriViewPasswordCell : DataGridViewTextBoxCell
{
    public override void InitializeEditingControl(int rowIndex, 
        object initialFormattedValue,
        DataGridViewCellStyle dataGridViewCellStyle)
    {
        base.InitializeEditingControl(rowIndex, 
            initialFormattedValue, dataGridViewCellStyle);
        ((TextBox)this.DataGridView.EditingControl).UseSystemPasswordChar = true;
    }
    protected override void Paint(Graphics graphics, 
        Rectangle clipBounds, Rectangle cellBounds,
        int rowIndex, DataGridViewElementStates cellState,
        object value, object formattedValue,
        string errorText, DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle, 
        DataGridViewPaintParts paintParts)
    {
        var i = $"{formattedValue}".Length;
        formattedValue = new string('●', i);
        base.Paint(graphics, clipBounds, cellBounds, rowIndex,
            cellState, value, formattedValue,
            errorText, cellStyle, advancedBorderStyle, paintParts);
    }
}

Not that i use winforms DataGrids. However...

You are killing the data with

e.Value = new string('\u2022', e.Value.ToString().Length);

However you are putting into a tag

 gvInstanceDetails.Rows[e.RowIndex].Tag = e.Value;

If you know the row you want, you just need to call

var myAwesomePassword = (string) gvInstanceDetails.Rows[someArbitaryRow].Tag

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM