6
votes

I have a datagridview bound to a datatable. The columns are not autogenerated, I create them in code. I want my user's to be able to add and delete a row, so I have AllowUserToAddRows = true, AllowUserToDeleteRows = true.

The problem is: when they select a row and press DEL, the information is replaced by the row cell's default values. The row does not go away.

What is this behavior (why/what is happening), and how can I get around it?

Here is my grid creation code:

    private void resetDowntimeGrid()
    {
        downtimeEntries = new DataTable();

        downtimeEntries.Columns.Add("Category", typeof(int));
        downtimeEntries.Columns.Add("HoursDown");
        downtimeEntries.Columns.Add("Reason");

        //deptDowntimeCategories.Select("", "ListOrder ASC");

        gridDowntime.Columns.Clear();

        DataGridViewComboBoxColumn cboCategory = new DataGridViewComboBoxColumn();
        {
            cboCategory.HeaderText = "Category";
            cboCategory.DataSource = deptDowntimeCategories;
            cboCategory.DisplayMember = "Name";
            cboCategory.ValueMember = "CategoryID";
            cboCategory.DataPropertyName = "Category";
            cboCategory.Width = Convert.ToInt16(gridDowntime.Width * 0.20);
            cboCategory.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
            cboCategory.AutoComplete = true;

            gridDowntime.Columns.Add(cboCategory);
        }

        DataGridViewTextBoxColumn txtDowntime = new DataGridViewTextBoxColumn();
        txtDowntime.HeaderText = "HoursDown";
        txtDowntime.DataPropertyName = "HoursDown";
        txtDowntime.Width = Convert.ToInt16(gridDowntime.Width * 0.15);
        gridDowntime.Columns.Add(txtDowntime);

        DataGridViewTextBoxColumn txtReason = new DataGridViewTextBoxColumn();
        txtReason.HeaderText = "Reason";
        txtReason.DataPropertyName = "Reason";
        txtReason.Width = Convert.ToInt16(gridDowntime.Width * 0.60);
        gridDowntime.Columns.Add(txtReason);

        gridDowntime.DataSource = downtimeEntries;

        lblStatus.Text = "Downtime grid reset.";
    }
3
Could you post some code showing how you are creating/binding data?Bryan Crosby
What do you mean when you say the row is replaced with 'default values'? I tried the code you provided and it works as expected. One thought is that the row selection mode is giving unexpected behaviour? I find that deleting rows without full row select can be confusing often.David Hall
@DavidHall -It looks like the row gets cleared, but doesn't disappear. And there is still the usual new row with the * beneath it. I just want (and expect) the * row to be left.MAW74656
This works just as expected when I try it. Can you provide all the code please. There will be some event handler that is interfering with the default behaviour. Possibly you have automatic database writes, something like that? Also, have you tried this in a completely empty sample form, then one it is working try adding in functionality until you find the problem.David Hall

3 Answers

7
votes

I created an empty winform and just put the grid code into it. The difference was how I had the DataGridView.EditMode set. I had it = EditOnEnter, but the delete works perfectly if I set it = EditOnKeystroke.

3
votes

Another reason why hitting Delete doesn't remove the rows is if you have the RowHeadersVisible property set to False, thus not showing the * in the left most column. With that fixed, @MAW74656's solution worked for me.

1
votes

Here's a quick sample that I did, minus two of your columns, using part of your code. I could not duplicate your problem. You may want to validate that you are actually selecting a value, clicking the value from the drop down, and then click 'Delete'. (In this case, I simply dragged a DataGridView from the toolbox to the form. I made no other modifications.)

public partial class Form1 : Form
{
       public Form1()
       {
           InitializeComponent();
       }

       private void button1_Click(object sender, EventArgs e)
       {
           DataTable myTable = new DataTable("MyTable");
           myTable.Columns.Add("CategoryID", typeof(int));
           myTable.Columns.Add("CategoryName", typeof(string));
           myTable.Rows.Add(new object[] { 1, "Small" });
           myTable.Rows.Add(new object[] { 2, "Medium" });
           myTable.Rows.Add(new object[] { 3, "Large" });

           DataGridViewComboBoxColumn cboCategory = new DataGridViewComboBoxColumn();
           cboCategory.HeaderText = "Category";
           cboCategory.DataSource = myTable;
           cboCategory.DisplayMember = "CategoryName";
           cboCategory.ValueMember = "CategoryID";
           cboCategory.DataPropertyName = "Category";
           cboCategory.Width = Convert.ToInt16(dataGridView1.Width * 0.20);
           cboCategory.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
           cboCategory.AutoComplete = true;

           dataGridView1.Columns.Add(cboCategory);

       }
}