Forum guidelines
Adding a new row to a databound dataGridView control
Posted By Walter Kiess on 12 Dec 2012
I have a DataGridView control named uxContactEmailAddressesGrd. It is data bound to a collection of email address objects. It has 3 columns: 
  1. Hidden: email Primary Key (PK) (int)
  2. shown: email address (string)
  3. Shown: email type (combobox, ValueMember=int, DisplayMember=String)
I've set the AllowUserToAddRows property of the grid to False to prevent the user from accidentally adding a new email address. They have to DoubleClick the grid to add a new row. I tried using uxContactEmailAddressesGrd.Rows.Add, but this is not allowed for databound grids. So I add a new row by setting AllowUserToAddRows property of the grid to True in the grid's doubleClick event and force editing of the 1st new cell in the new row. This works fine and a new row is added to the end of the grid, but as soon as I start typing into the first cell, a new row appears under the current (new) row. I don't want this as it may confuse my users. I figure I can simply turn off the AllowUserToAddRows property by setting it back to False as soon as a key is pressed. Unfortunately the Grid's KeyDown event is not triggered because the cell is in Edit Mode. After a bit of hunting in the C# forums, I found an article that advised I should subclass the control, which I did (see the code below).

    public sealed class XDataGridView : DataGridView
        private bool _singleUpdateOnly = true;

        public bool SingleUpdateOnly
            get { return _singleUpdateOnly; }
            set { _singleUpdateOnly = value; }

        [Description("Disallows user adding rows as soon as a key is struck to ensure no blank row at bottom of grid")]
        protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
            if (SingleUpdateOnly)
                //AllowUserToAddRows = false;

            return base.ProcessCmdKey(ref msg, keyData);

This seems to work fine with one slight problem: The 1st char I type in the cell is always swallowed up, i.e. I have to press the 1st char of a word twice for it to be shown in the cell.

What have I done wrong to cause this? I thought I had it licked by continuing to call the base class with the entered char, but seemingly not. Can anyone help with this problem? How do I stop it from swallowing the 1st char type?

Re: Adding a new row to a databound dataGridView control
Posted By Walter Kiess on 18 Dec 2012  
I've had very little response to this question on this forum and others. It must be a very difficult problem, or I'm simply expecting too much from the DataGridView control.
After many hours of trial and error, I have settled on a solution which does not require subclassing. The solution is not exactly what I wanted, i.e. to prevent another another row from being appended to the bottom of the grid once the user begins typing into the newly added row, but it comes close. I use the CellLeave event to turn off AllowUserToAddRows. When the user presses Tab or Enter to enter the data into the 1st cell, this effectively removes the newly added row from the grid leaving the user in the next cell of the newly added (last) row of the grid (without an empty row underneath). Not elegant, but at least mostly functional. Here's the code:
private void uxContactEmailAddressesGrd_CellLeave(object sender, DataGridViewCellEventArgs e)
        uxContactEmailAddressesGrd.AllowUserToAddRows = false;
Maybe one day someone else will come across this problem and find a solution more elegant than mine. That'd be great. Make sure you post your solution to this site for others to use.

Download Free e-Books


Spire.Doc - Free .NET Word API
Use Spire.Doc to create, read, write, print, and convert word documents to OpenXML, RTF, TXT, XPS, EPUB, EMF, HTML, Image and PDF.