Windows > Windows Forms Forums > Windows Forms Data Controls and Databinding > How to pop-up text edit window in DataGridView?
Ask a questionAsk a question
 

AnswerHow to pop-up text edit window in DataGridView?

  • Monday, December 12, 2005 4:27 PMphilipsh Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    One of the textboxes in my DataGridView holds lots of text (like a detailed description). I'd like to present a large text editing window to the user when she edits this column.  Is there any way to do this?

    Thanks

Answers

  • Monday, December 12, 2005 8:18 PMMark Rideout Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    The easiest way to do this is to handle the EditingControlShowing or the CellBeginEdit event and basically perform a ShowDialog call on your pop-up text window. I tried this with a second form (form2) that has a textbox and button on the form. I have a public method called ShowDialog that takes a string value and returns a string value:

    public string ShowDialog(string formattedValue)
    {
        this.textBox1.Text = formattedValue;
        this.ShowDialog();
        return this.textBox1.Text;
    }
    private void button1_Click(object sender, EventArgs e)
    {
        this.Close();
    }

     

    Next inside of the CellBeginEdit event handler, I create an instance of form2 and call the new ShowDialog method passing in the cell's FormattedValue. When the ShowDialgo call returns, I perform an anonymous delegate to end the cell's editing. This is necessary because the cell will still attempt to be in edit mode after your dialog closes. The BeginInvoke call ensures that the EndEdit call occurs after the CellBeginEdit call finishes. C# with the anonymous delegate makes this easy to code:

    private void dataGridView1_EditingControlShowing(...)
    {
        Point c = dataGridView1.CurrentCellAddress;

        Form2 f = new Form2();

        string formattedValue = f.ShowDialog(dataGridView1[c.X, c.Y].FormattedValue.ToString());

        dataGridView1.BeginInvoke((MethodInvoker)delegate()
        {
            dataGridView1.EndEdit();
            dataGridView1[c.X, c.Y].Value = formattedValue;
        });
    }

     
    In VB you'll need to create a method that performs the action contained in the anonymous delegate body.

    Ok, the above is the easiest way, but it does have one drawback -- if you allow the user to enter edit mode on a keystroke, the keystroke that the user starts with will not be sent to your textbox in your popup dialog. This is because the DataGridView forwards the keystroke to the editing control. You can do the similar work by creating a custom DataGridViewCell that overrides InitializeEditingControl and KeyEntersEditMode. In the KeyEntersEditMode method you'll want to set a boolean and remember the keystroke (if the keystroke is one that starts edit) and then later, in your CellBeginEdit forward the keystroke to the textbox contained on your popup dialog. The DataGridView p/invokes the SendMessage api to forward the keystroke.

    If you can go with the EditMode of F2 or double-click on the cell then you'll be fine with the first (easy) approach.

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

All Replies

  • Monday, December 12, 2005 8:18 PMMark Rideout Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    The easiest way to do this is to handle the EditingControlShowing or the CellBeginEdit event and basically perform a ShowDialog call on your pop-up text window. I tried this with a second form (form2) that has a textbox and button on the form. I have a public method called ShowDialog that takes a string value and returns a string value:

    public string ShowDialog(string formattedValue)
    {
        this.textBox1.Text = formattedValue;
        this.ShowDialog();
        return this.textBox1.Text;
    }
    private void button1_Click(object sender, EventArgs e)
    {
        this.Close();
    }

     

    Next inside of the CellBeginEdit event handler, I create an instance of form2 and call the new ShowDialog method passing in the cell's FormattedValue. When the ShowDialgo call returns, I perform an anonymous delegate to end the cell's editing. This is necessary because the cell will still attempt to be in edit mode after your dialog closes. The BeginInvoke call ensures that the EndEdit call occurs after the CellBeginEdit call finishes. C# with the anonymous delegate makes this easy to code:

    private void dataGridView1_EditingControlShowing(...)
    {
        Point c = dataGridView1.CurrentCellAddress;

        Form2 f = new Form2();

        string formattedValue = f.ShowDialog(dataGridView1[c.X, c.Y].FormattedValue.ToString());

        dataGridView1.BeginInvoke((MethodInvoker)delegate()
        {
            dataGridView1.EndEdit();
            dataGridView1[c.X, c.Y].Value = formattedValue;
        });
    }

     
    In VB you'll need to create a method that performs the action contained in the anonymous delegate body.

    Ok, the above is the easiest way, but it does have one drawback -- if you allow the user to enter edit mode on a keystroke, the keystroke that the user starts with will not be sent to your textbox in your popup dialog. This is because the DataGridView forwards the keystroke to the editing control. You can do the similar work by creating a custom DataGridViewCell that overrides InitializeEditingControl and KeyEntersEditMode. In the KeyEntersEditMode method you'll want to set a boolean and remember the keystroke (if the keystroke is one that starts edit) and then later, in your CellBeginEdit forward the keystroke to the textbox contained on your popup dialog. The DataGridView p/invokes the SendMessage api to forward the keystroke.

    If you can go with the EditMode of F2 or double-click on the cell then you'll be fine with the first (easy) approach.

    -mark
    DataGridView Program Manager
    Microsoft
    This post is provided "as-is"
  • Monday, December 12, 2005 9:06 PMphilipsh Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    The easy way works for us.   Thanks Mark.

        Phil
  • Monday, December 12, 2005 9:45 PMMark Rideout Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Note that if you want to use a fancy popup style window instead of a dialog, you can use the ToolStripDropDown class. Here is some of my code that I used. Same issues apply as with the "easy" option I described above. You'll also want to create some sort of "commit" keyboard action so the user doesn't have to click out of the popup window. Here is my code in my CellBeginEdit handler


    dropDownClosed = false;
    Point c = dataGridView1.CurrentCellAddress;
    formattedValue = dataGridView1[c.X, c.Y].FormattedValue.ToString();

    tsdd = new ToolStripDropDown();
    tsdd.Opened += new EventHandler(tsdd_Opened);
    tsdd.AutoSize = true;

    TextBox tb = new TextBox();
    tb.Multiline = true;
    tb.Text = formattedValue;
    tb.AcceptsReturn = true;

    tbh = new ToolStripControlHost(tb, "textbox");
    tbh.Padding = new Padding(0);
    tbh.AutoSize = false;
    tbh.Size = new Size(200, 200);

    tsdd.Items.Add(tbh);
    tsdd.Padding = new Padding(0);
    tsdd.Closing += new ToolStripDropDownClosingEventHandler(tsdd_Closing);
    tsdd.Show(dataGridView1, dataGridView1.GetCellDisplayRectangle(c.X, c.Y, true).Location);

    while (!this.dropDownClosed)
    {
        Application.DoEvents();
    }

    dataGridView1.BeginInvoke((MethodInvoker)delegate()
    {
        dataGridView1.EndEdit();
        dataGridView1[c.X, c.Y].Value = this.formattedValue;
    });

     

    Here is my ToolStripDropDown Closing event handler code:

    this.formattedValue = tsdd.Items[0].Text;
    this.dropDownClosed = true;

     
    Here is the code forr the ToolStripDropDown Opened event handler:

    tbh.Focus();
     

    And here is some variables that I declare:

    ToolStripDropDown tsdd;
    bool dropDownClosed;
    string formattedValue;
    ToolStripControlHost tbh;

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

  • Monday, June 11, 2007 9:00 AMpserranop Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi, Mark:

     

    It is possible show the window (showdialog) in the currentcell?

     

    If I try it with:

     

    form2.Location = dataGridView1.PointToClient(dataGridView1.GetCellDisplayRectangle(e.ColumnIndex,
    e.RowIndex, false).Location);

     

    But it don't work fine.

     

    Any ideas?

     

    Thanks in advance.


     

  • Tuesday, February 12, 2008 3:34 AMphanf2 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Does anyone have a solution to get the current cells x y position? I've also tried the above code which doesn't work?

     

    Thanks.