none
Multiline TextBox in Windows Forms DataGridView Cells RRS feed

  • Question

  • Hi,all
     I have a DataGridView which contains a DataGridViewTextBoxColumn. While in edit mode, I want the cell to be ComboBox style,click on which I want it to drop a muliti-line text editor,which like the  muliti-line text editor in the PropertyGrid. Could someone be so kind as to give any hint? Thanks!

    Saturday, April 21, 2007 1:55 PM

Answers

  • To host a TextEditor control as you described, we can take the following steps:
    1). Create a UserControl say TextEditorControl as shown in the following sample to host a TextBox and a Button, override the Paint event of the button to make it appear to be a combo button. Handle the click event of this button to drop / un-drop a multi-line TextBox for user to write.
    2). Sub-class the DataGridView class, override the ProcessDialogKey method and ProcessKeyPreview method to filter keys, which allows the Enter key, arrow keys to be used in the multi-line dropdown TextBox. Use this inherited control instead of the standard one.
    3). Add TextEditorControl and a TextBox into the control collection,initially make them invisable.Handle the CellBeginEdit  event to show the TextEditorControl in the current cell, and handle the CellEndEdit event set the text typed in the TextEditorControl to the current cell.

    The following is a simple sample I write for your information, I've no much time to dig into it so it maybe buggy, but this sample could at least give you some base to go from.


    Code Snippet

    namespace Sample6

    {

        public partial class DgvTextBoxEditor : Form

        {

            public DgvTextBoxEditor()

            {

                InitializeComponent();

            }

     

            TextBox textBox1;

            TextEditorControl textEditorControl1;

            DataGridViewFilterEnter dataGridView1;

     

            private void DgvTextBoxEditor_Load(object sender, EventArgs e)

            {

                DataTable dt = new DataTable();

                dt.Columns.Add("name");

                dt.Columns.Add("text");

                for (int j = 0; j < 5; j++)

                {

                    dt.Rows.Add("aa");

                }

                this.dataGridView1 = new DataGridViewFilterEnter();

                this.dataGridView1.Location = new Point(10, 20);

                this.dataGridView1.Size = new Size(380, 300);

                this.Controls.Add(this.dataGridView1);

     

                this.dataGridView1.DataSource = dt;

                //this.dataGridView1.Columns[1].DefaultCellStyle.WrapMode = DataGridViewTriState.True;

               // this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

     

                this.textBox1 = new TextBox();

                this.textBox1.Multiline = true;

                this.textBox1.Width = 180;

                this.textBox1.Height = 100;

                this.textBox1.Visible = false;

                this.textBox1.BorderStyle = BorderStyle.FixedSingle;

                this.textBox1.KeyDown += new KeyEventHandler(textBox1_KeyDown);

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

     

                this.textEditorControl1 = new TextEditorControl();

                this.textEditorControl1.EditorBox = this.textBox1;

                this.textEditorControl1.Visible = false;

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

     

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

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

            }

     

            void textBox1_KeyDown(object sender, KeyEventArgs e)

            {

                if (e.Control && e.KeyCode == Keys.Enter)

                {

                    this.textEditorControl1.Text = this.textBox1.Text;

                    this.textBox1.Visible = false;

                }

            }

     

            void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)

            {

                if (e.ColumnIndex == 1)

                {

                    this.textBox1.Text = this.dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString();

                    this.textEditorControl1.Text = this.dataGridView1[e.ColumnIndex,e.RowIndex].Value.ToString();

                    Rectangle rect = this.dataGridView1.GetCellDisplayRectangle(e.ColumnIndex,

                        e.RowIndex, true);

                    Point p = new Point();

                    p.X = rect.Left - (this.textBox1.Width - rect.Width);

                    p.Y = rect.Bottom;

                    this.textBox1.Location = p;

                    this.textEditorControl1.Size = rect.Size;

                    this.textEditorControl1.Location = rect.Location;

                    this.textEditorControl1.Visible = true;

                }

            }

     

            void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)

            {

                if (e.ColumnIndex == 1)

                {

                    this.dataGridView1[e.ColumnIndex, e.RowIndex].Value = this.textEditorControl1.Text;

                }

            }

        }

     

        class TextEditorControl : UserControl

        {

            private TextBox textbox1;

            private TextBox editorBox;

            private Button button1;

            private bool isDroped;

     

            public TextEditorControl():base()

            {

                this.textbox1 = new TextBox();

                this.textbox1.TextChanged += new EventHandler(textbox1_TextChanged);

                this.textbox1.KeyDown += new KeyEventHandler(textbox1_KeyDown);

     

                this.button1 = new Button();

                this.button1.Size = new Size(18, this.textbox1.Height);

                this.button1.Left = this.textbox1.Right - 2;

                this.button1.Paint += new PaintEventHandler(button1_Paint);

                this.button1.Click += new EventHandler(button1_Click);

     

                this.isDroped = false;

     

                this.Width = this.textbox1.Width + this.button1.Width;

                this.Height = this.textbox1.Height;

                this.Controls.Add(this.textbox1);

                this.Controls.Add(this.button1);

            }

     

            void textbox1_KeyDown(object sender, KeyEventArgs e)

            {

                this.editorBox.Visible = false;

            }

     

            void textbox1_TextChanged(object sender, EventArgs e)

            {

                this.Text = this.textbox1.Text;

                //this.editorBox.Text = this.textbox1.Text;

            }

     

            void button1_Click(object sender, EventArgs e)

            {

                this.isDroped = !this.isDroped;

                if (this.isDroped)

                {

                    this.editorBox.Visible = true;

                    this.editorBox.Text = this.Text;

                }

                else

                {

                    this.editorBox.Visible = false;

                    this.textbox1.Text = this.editorBox.Text;

                }

            }

     

            void button1_Paint(object sender, PaintEventArgs e)

            {

                ControlPaint.DrawComboButton(e.Graphics, e.ClipRectangle, ButtonState.Normal);

            }

     

            public TextBox EditorBox

            {

                set { this.editorBox = value; }

            }

     

            public override string Text

            {

                get

                {

                    return base.Text;

                }

                set

                {

                    base.Text = value;

                    this.textbox1.Text = value;

                }

            }

     

            protected override void OnSizeChanged(EventArgs e)

            {

                base.OnSizeChanged(e);

                this.textbox1.Width = this.Width - this.button1.Width;

                this.button1.Left = this.textbox1.Right - 2;

            }

        }

     

        class DataGridViewFilterEnter : DataGridView

        {

            protected override bool ProcessDialogKey(Keys keyData)

            {

                if (keyData == Keys.Enter)

                    return false;

                return base.ProcessDialogKey(keyData);

            }

     

            protected override bool ProcessKeyPreview(ref Message m)

            {

                KeyEventArgs args1 = new KeyEventArgs(((Keys)((int)m.WParam)) | Control.ModifierKeys);

                switch (args1.KeyCode)

                {

                    case Keys.Enter:

                    case Keys.Left:

                    case Keys.Right:

                    case Keys.Down:

                    case Keys.Up:

                        return false;

                }

                return base.ProcessKeyPreview(ref m);

            }

        }

    }

     

    Monday, April 23, 2007 3:58 AM

All replies

  • Saturday, April 21, 2007 3:57 PM
  • To host a TextEditor control as you described, we can take the following steps:
    1). Create a UserControl say TextEditorControl as shown in the following sample to host a TextBox and a Button, override the Paint event of the button to make it appear to be a combo button. Handle the click event of this button to drop / un-drop a multi-line TextBox for user to write.
    2). Sub-class the DataGridView class, override the ProcessDialogKey method and ProcessKeyPreview method to filter keys, which allows the Enter key, arrow keys to be used in the multi-line dropdown TextBox. Use this inherited control instead of the standard one.
    3). Add TextEditorControl and a TextBox into the control collection,initially make them invisable.Handle the CellBeginEdit  event to show the TextEditorControl in the current cell, and handle the CellEndEdit event set the text typed in the TextEditorControl to the current cell.

    The following is a simple sample I write for your information, I've no much time to dig into it so it maybe buggy, but this sample could at least give you some base to go from.


    Code Snippet

    namespace Sample6

    {

        public partial class DgvTextBoxEditor : Form

        {

            public DgvTextBoxEditor()

            {

                InitializeComponent();

            }

     

            TextBox textBox1;

            TextEditorControl textEditorControl1;

            DataGridViewFilterEnter dataGridView1;

     

            private void DgvTextBoxEditor_Load(object sender, EventArgs e)

            {

                DataTable dt = new DataTable();

                dt.Columns.Add("name");

                dt.Columns.Add("text");

                for (int j = 0; j < 5; j++)

                {

                    dt.Rows.Add("aa");

                }

                this.dataGridView1 = new DataGridViewFilterEnter();

                this.dataGridView1.Location = new Point(10, 20);

                this.dataGridView1.Size = new Size(380, 300);

                this.Controls.Add(this.dataGridView1);

     

                this.dataGridView1.DataSource = dt;

                //this.dataGridView1.Columns[1].DefaultCellStyle.WrapMode = DataGridViewTriState.True;

               // this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

     

                this.textBox1 = new TextBox();

                this.textBox1.Multiline = true;

                this.textBox1.Width = 180;

                this.textBox1.Height = 100;

                this.textBox1.Visible = false;

                this.textBox1.BorderStyle = BorderStyle.FixedSingle;

                this.textBox1.KeyDown += new KeyEventHandler(textBox1_KeyDown);

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

     

                this.textEditorControl1 = new TextEditorControl();

                this.textEditorControl1.EditorBox = this.textBox1;

                this.textEditorControl1.Visible = false;

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

     

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

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

            }

     

            void textBox1_KeyDown(object sender, KeyEventArgs e)

            {

                if (e.Control && e.KeyCode == Keys.Enter)

                {

                    this.textEditorControl1.Text = this.textBox1.Text;

                    this.textBox1.Visible = false;

                }

            }

     

            void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)

            {

                if (e.ColumnIndex == 1)

                {

                    this.textBox1.Text = this.dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString();

                    this.textEditorControl1.Text = this.dataGridView1[e.ColumnIndex,e.RowIndex].Value.ToString();

                    Rectangle rect = this.dataGridView1.GetCellDisplayRectangle(e.ColumnIndex,

                        e.RowIndex, true);

                    Point p = new Point();

                    p.X = rect.Left - (this.textBox1.Width - rect.Width);

                    p.Y = rect.Bottom;

                    this.textBox1.Location = p;

                    this.textEditorControl1.Size = rect.Size;

                    this.textEditorControl1.Location = rect.Location;

                    this.textEditorControl1.Visible = true;

                }

            }

     

            void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)

            {

                if (e.ColumnIndex == 1)

                {

                    this.dataGridView1[e.ColumnIndex, e.RowIndex].Value = this.textEditorControl1.Text;

                }

            }

        }

     

        class TextEditorControl : UserControl

        {

            private TextBox textbox1;

            private TextBox editorBox;

            private Button button1;

            private bool isDroped;

     

            public TextEditorControl():base()

            {

                this.textbox1 = new TextBox();

                this.textbox1.TextChanged += new EventHandler(textbox1_TextChanged);

                this.textbox1.KeyDown += new KeyEventHandler(textbox1_KeyDown);

     

                this.button1 = new Button();

                this.button1.Size = new Size(18, this.textbox1.Height);

                this.button1.Left = this.textbox1.Right - 2;

                this.button1.Paint += new PaintEventHandler(button1_Paint);

                this.button1.Click += new EventHandler(button1_Click);

     

                this.isDroped = false;

     

                this.Width = this.textbox1.Width + this.button1.Width;

                this.Height = this.textbox1.Height;

                this.Controls.Add(this.textbox1);

                this.Controls.Add(this.button1);

            }

     

            void textbox1_KeyDown(object sender, KeyEventArgs e)

            {

                this.editorBox.Visible = false;

            }

     

            void textbox1_TextChanged(object sender, EventArgs e)

            {

                this.Text = this.textbox1.Text;

                //this.editorBox.Text = this.textbox1.Text;

            }

     

            void button1_Click(object sender, EventArgs e)

            {

                this.isDroped = !this.isDroped;

                if (this.isDroped)

                {

                    this.editorBox.Visible = true;

                    this.editorBox.Text = this.Text;

                }

                else

                {

                    this.editorBox.Visible = false;

                    this.textbox1.Text = this.editorBox.Text;

                }

            }

     

            void button1_Paint(object sender, PaintEventArgs e)

            {

                ControlPaint.DrawComboButton(e.Graphics, e.ClipRectangle, ButtonState.Normal);

            }

     

            public TextBox EditorBox

            {

                set { this.editorBox = value; }

            }

     

            public override string Text

            {

                get

                {

                    return base.Text;

                }

                set

                {

                    base.Text = value;

                    this.textbox1.Text = value;

                }

            }

     

            protected override void OnSizeChanged(EventArgs e)

            {

                base.OnSizeChanged(e);

                this.textbox1.Width = this.Width - this.button1.Width;

                this.button1.Left = this.textbox1.Right - 2;

            }

        }

     

        class DataGridViewFilterEnter : DataGridView

        {

            protected override bool ProcessDialogKey(Keys keyData)

            {

                if (keyData == Keys.Enter)

                    return false;

                return base.ProcessDialogKey(keyData);

            }

     

            protected override bool ProcessKeyPreview(ref Message m)

            {

                KeyEventArgs args1 = new KeyEventArgs(((Keys)((int)m.WParam)) | Control.ModifierKeys);

                switch (args1.KeyCode)

                {

                    case Keys.Enter:

                    case Keys.Left:

                    case Keys.Right:

                    case Keys.Down:

                    case Keys.Up:

                        return false;

                }

                return base.ProcessKeyPreview(ref m);

            }

        }

    }

     

    Monday, April 23, 2007 3:58 AM