How to pop-up text edit window in DataGridView?
- 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
- 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:
In VB you'll need to create a method that performs the action contained in the anonymous delegate body.
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;
});
}
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
- 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:
In VB you'll need to create a method that performs the action contained in the anonymous delegate body.
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;
});
}
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" - The easy way works for us. Thanks Mark.
Phil 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
Here is my ToolStripDropDown Closing event handler code:
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 the code forr the ToolStripDropDown Opened event handler:
this.formattedValue = tsdd.Items[0].Text;
this.dropDownClosed = true;
tbh.Focus();
And here is some variables that I declare:
-mark
ToolStripDropDown tsdd;
bool dropDownClosed;
string formattedValue;
ToolStripControlHost tbh;
DataGridView Program Manager
Microsoft
This post is provided "as-is"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.
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.


