Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > Adding a new Row to the DataGridView programmatically (DataGridView.AllowUserToAddRow = false) and then Cancel adding by press ESC
 

Adding a new Row to the DataGridView programmatically (DataGridView.AllowUserToAddRow = false) and then Cancel adding by press ESC

hi Developers..
I have a Form that contains a DataGridView and a Button and I want to bind this DataGridView to a Custom data source (BindingList) and I want to add a new Item to the DataGridView only when I Click the Button (( so dataGridView.AllowUserToAddRows = false )) , But the problem is that if I Click a Button to add a new row (item ) to the DataGridView , But then I decided to Cancel adding a new Item by pressing ESC the new row will not deleted
so what the solution

Thanks in advance
alladeen88  Sunday, September 06, 2009 9:16 PM
Hi alladeen88,

If we use a BindingList, we do not need to implement the ICancelAddNew interface, BindingList already implements ICancelAddNew. We can check whether a row has uncommited changes via the IsCurrentRowDirty property.
Based on my understanding, we can create a custom BindingList to simplify the cancel new logic. This is a sample:
    //The item object, you can change this to your object.
    public class DataSample
    {
        public int Id { set; get; }
        public string Name { set; get; }
    }

    //Custom binding list.
    public class MyBindingList : BindingList<DataSample>
    {
        //The index of the new row.
        private int _newRowIndex = -1;

        protected override object AddNewCore()
        {
            object newItem = base.AddNewCore();
            //Save the new row index.
            _newRowIndex = this.Count - 1;
            return newItem;
        }

        public void CancelNew()
        {
            //Cancel adding if a new row is added.
            if (_newRowIndex != -1)
                base.CancelNew(_newRowIndex);
        }

        //Used to check if a new row is added.
        public bool HasNewRow
        {
            get { return _newRowIndex != -1; }
        }
    }
This is the code snippet in the main form:
        private void DGVCancelAddingForm_Load(object sender, EventArgs e)
        {
            //Disallow new row to be inserted by users.
            this.dataGridView1.AllowUserToAddRows = false;
            //Bind the bind list.
            this.dataGridView1.DataSource = GetBindingList();

            //Have the form be able to retrieve key when some controls got focus.
            this.KeyPreview = true;
            //Handle this event to deleted the new row by pressing Escape.
            this.KeyUp += new KeyEventHandler(DGVCancelAddingForm_KeyUp);
        }

        void DGVCancelAddingForm_KeyUp(object sender, KeyEventArgs e)
        {
            MyBindingList list = this.dataGridView1.DataSource as MyBindingList;
            if (e.KeyCode == Keys.Escape && list.HasNewRow && this.dataGridView1.IsCurrentRowDirty)
            {
                //cancel new row adding if a new row is added and the current row has values uncommited.
                list.CancelNew();
            }
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            //Click button1 to add a new item.
            IBindingList list = this.dataGridView1.DataSource as IBindingList;
            list.AddNew();
        }
Let me know if this helps or not.
Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
Aland Li  Thursday, September 10, 2009 5:05 AM
Hi alladeen88,

DataGridView or Form does not directly support deleting by pressing Escape key, we need to handle it by ourselves. The code snippet below shows how to implement deleting a new added row in DataGridView by pressing Escape key:
private object _newItem = null;
private void DGVCancelAddingForm_Load(object sender, EventArgs e)
{
    //Disallow new row to be inserted by users.
    this.dataGridView1.AllowUserToAddRows = false;
    //Bind the bind list.
    this.dataGridView1.DataSource = GetBindingList();

    //Have the form be able to retrieve key when some controls got focus.
    this.KeyPreview = true;
    //Handle this event to deleted the new row by pressing Escape.
    this.KeyUp += new KeyEventHandler(DGVCancelAddingForm_KeyUp);
}

void DGVCancelAddingForm_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Escape && _newItem != null)
    {
        //If a new row is added and the Esc is pressed, delete the new added item.
        IBindingList list = this.dataGridView1.DataSource as IBindingList;
        list.Remove(_newItem);
        //Reset new item to null.
        _newItem = null;
    }
}
Let me know if this does not help.
Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
Aland Li  Tuesday, September 08, 2009 9:42 AM
hi Aland Li
but in this snippet of code the variable _newItem will always be null !!

thanks
alladeen88  Tuesday, September 08, 2009 11:59 AM
Hi alladeen88,

Sorry for not providing the complete code snippet. We need to set the _newItem to the new added item when we add a new item. This is a code snippet:
private void buttonAdd_Click(object sender, EventArgs e)
{
    //Click button1 to add a new item.
    IBindingList list = this.dataGridView1.DataSource as IBindingList;
    _newItem = list.AddNew();
}
Regards,
Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
Aland Li  Wednesday, September 09, 2009 2:52 AM
hi Aland
That is what I want. But there is another problem in the snippet above , the last row in the DataGridView will always be deleted when press ESC , but what I need to do is to delete last row only if the last row is new and has uncommitted changes .
I think about ICancelAddNew interface and IsCurrentRowDirty property but I don't know exactly how to use them

Regards
alladeen88  Thursday, September 10, 2009 2:53 AM
Hi alladeen88,

If we use a BindingList, we do not need to implement the ICancelAddNew interface, BindingList already implements ICancelAddNew. We can check whether a row has uncommited changes via the IsCurrentRowDirty property.
Based on my understanding, we can create a custom BindingList to simplify the cancel new logic. This is a sample:
    //The item object, you can change this to your object.
    public class DataSample
    {
        public int Id { set; get; }
        public string Name { set; get; }
    }

    //Custom binding list.
    public class MyBindingList : BindingList<DataSample>
    {
        //The index of the new row.
        private int _newRowIndex = -1;

        protected override object AddNewCore()
        {
            object newItem = base.AddNewCore();
            //Save the new row index.
            _newRowIndex = this.Count - 1;
            return newItem;
        }

        public void CancelNew()
        {
            //Cancel adding if a new row is added.
            if (_newRowIndex != -1)
                base.CancelNew(_newRowIndex);
        }

        //Used to check if a new row is added.
        public bool HasNewRow
        {
            get { return _newRowIndex != -1; }
        }
    }
This is the code snippet in the main form:
        private void DGVCancelAddingForm_Load(object sender, EventArgs e)
        {
            //Disallow new row to be inserted by users.
            this.dataGridView1.AllowUserToAddRows = false;
            //Bind the bind list.
            this.dataGridView1.DataSource = GetBindingList();

            //Have the form be able to retrieve key when some controls got focus.
            this.KeyPreview = true;
            //Handle this event to deleted the new row by pressing Escape.
            this.KeyUp += new KeyEventHandler(DGVCancelAddingForm_KeyUp);
        }

        void DGVCancelAddingForm_KeyUp(object sender, KeyEventArgs e)
        {
            MyBindingList list = this.dataGridView1.DataSource as MyBindingList;
            if (e.KeyCode == Keys.Escape && list.HasNewRow && this.dataGridView1.IsCurrentRowDirty)
            {
                //cancel new row adding if a new row is added and the current row has values uncommited.
                list.CancelNew();
            }
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            //Click button1 to add a new item.
            IBindingList list = this.dataGridView1.DataSource as IBindingList;
            list.AddNew();
        }
Let me know if this helps or not.
Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
Aland Li  Thursday, September 10, 2009 5:05 AM
hi Aland
Sorry for the delay , and thanks alot ,that really what I need .

thanks
alladeen88  Tuesday, September 15, 2009 12:36 AM

You can use google to search for other answers

Custom Search

More Threads

• refresh values in a DATASET dynamically in VB 2005
• Merge a particular column header in DataGridView C#
• combobox
• Help: DataGridView.AutoSizeRows
• datagrid control and sql database
• How set ForeColor in PropertyGrid?
• How to change previous DataGrid selected item back color
• DataGridView CellContentClick how do I get the row information for that cell click?
• Editable Hyperlink Column (DataGridViewLinkColumn)
• Set and Get Files