Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
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 grid control, which I did (see the code below).

C#
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?
Posted

These are just thoughts to work with and may not be the full answer.

You might want to look at something around EditMode property instead of "AllowUserToAddRows" for update capabilities.

Might be parted with IsCellInUpdateMode and/or on click events to avoid the first char getting ignored, becuase that first char is the action of the "Press any key to update" that is saying the cell should be getting updated.

This should help out with those two issues.
 
Share this answer
 
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:

C#
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.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900