Search code examples
c#.netwinformsdatagridviewmaskedtextbox

Focus and Double Click problem in a DataGridView cell that contains a MaskedTextBox


I have a problem when trying to edit a cell that contains a maskedtextbox:

If I try to edit the field I need to:

  1. double click on the cell (on this step the maskedtextbox becomes visible)
  2. click on the field again to begin edit
  3. set cursor "manually" to maskedtextbox first position

(4. start entering value)

It is possible somehow to avoid "manual" focusing to the maskedtextbox first position? (for example on single or double click : set visible the maskedtextbox and the same time set focus / cursor on the first position for the maskedtextbox )

I tried with: focus(), select(), SelectionStart, CurrentCell but without luck.

I added a MaskedTextbox to a DataGridView cell in the following way:

public Insert()
    {
        InitializeComponent();

        this.maskedTextBox = new MaskedTextBox();

        this.maskedTextBox.Visible = false;

        this.dataGridView1.Controls.Add(this.maskedTextBox);

        this.dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit);

        this.dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);

        this.dataGridView1.Scroll += new ScrollEventHandler(dataGridView1_Scroll);
    }

    void dataGridView1_Scroll(object sender, ScrollEventArgs e)
    {
        if (this.maskedTextBox.Visible)
        {
            Rectangle rect = this.dataGridView1.GetCellDisplayRectangle(
                this.dataGridView1.CurrentCell.ColumnIndex,
                this.dataGridView1.CurrentCell.RowIndex, true);
            this.maskedTextBox.Location = rect.Location;
        }
    }
    void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
    {
        if (e.ColumnIndex == this.dataGridView1.Columns[4].Index || e.ColumnIndex == this.dataGridView1.Columns[5].Index && e.RowIndex > -1)
        {
            string type = "";
            if (this.dataGridView1[e.ColumnIndex, e.RowIndex].Value != null)
                type = this.dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString();

            this.maskedTextBox.Mask = "0000.00.00";
            Rectangle rect =
               this.dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);

            this.maskedTextBox.Location = rect.Location;
            this.maskedTextBox.Size = rect.Size;
            this.maskedTextBox.Text = "";

            if (this.dataGridView1[e.ColumnIndex, e.RowIndex].Value != null)
            {
                this.maskedTextBox.Text = this.dataGridView1[e.ColumnIndex,
                    e.RowIndex].Value.ToString();
            }
            this.maskedTextBox.Visible = true;
            this.maskedTextBox.Focus(); //tried
            this.maskedTextBox.Select(0, 0);
            this.maskedTextBox.SelectionStart =0 ;
            dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
        }
    }
void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
if (this.maskedTextBox.Visible && (e.ColumnIndex == this.dataGridView1.Columns["TEST"].Index && e.RowIndex > -1))
            {
                this.dataGridView1.CurrentCell.Value = maskedTextBox.Text;
                this.maskedTextBox.Visible = false;
            }
        }

Solution

  • The control probably needs to get the focus after the BeginEdit method is complete, so try it this way:

    this.BeginInvoke(new Action(() => {
      this.maskedTextBox.Visible = true;
      this.maskedTextBox.Focus();
      this.maskedTextBox.Select(0, 0);
    }));