Question

I'm in a struggle with the DataGridView: I do have a BindingList of some simple objects that implement INotifyPropertyChanged. The DataGridView's datasource is set to this BindingList. Now I need to add an object to the list by hitting the "+" key. When an object is added, it should appear as a new row and it shall become the current row. As the CurrentRow-property is readonly, I iterate through all rows, check if its bound item is the newly created object, and if it is, I set this row to "Selected = true;"

The problem: although the new object and thereby a new row gets inserted and selected in the DataGridView, it still is not the CurrentRow! It does not become the CurrentRow unless I do a mouse click into this new row.

In this test program you can add new objects (and thereby rows) with the "+" key, and with the "i" key the data-bound object of the CurrentRow is shown in a MessageBox.

How can I make a newly added object become the CurrentObject? Thanks for your help!

Here's the sample:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        BindingList<item> myItems;

        public Form1()
        {
            InitializeComponent();
            myItems = new BindingList<item>();

            for (int i = 1; i <= 10; i++)
            {
                myItems.Add(new item(i));
            }

            dataGridView1.DataSource = myItems;
        }

        public void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Add)
            {
                addItem();
            }
        }

        public void addItem()
        {
            item i = new item(myItems.Count + 1);
            myItems.Add(i);
            foreach (DataGridViewRow dr in dataGridView1.Rows)
            {
                if (dr.DataBoundItem == i)
                {
                    dr.Selected = true;
                }
            }
        }

        private void btAdd_Click(object sender, EventArgs e)
        {
            addItem();
        }

        private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Add)
            {
                addItem();
            }
            if (e.KeyCode == Keys.I)
            {
                MessageBox.Show(((item)dataGridView1.CurrentRow.DataBoundItem).title);
            }
        }
    }

    public class item : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private int _id;
        public int id {
            get
            {
                return _id;
            }
            set
            {
                this.title = "This is item number " + value.ToString();
                _id = value;
                InvokePropertyChanged(new PropertyChangedEventArgs("id"));
            }
        }

        private string _title;
        public string title {
            get
            {
                return _title;
            }
            set
            {
                _title = value;
                InvokePropertyChanged(new PropertyChangedEventArgs("title"));
            }
        }

        public item(int id)
        {
            this.id = id;
        }

        #region Implementation of INotifyPropertyChanged
        public void InvokePropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, e);
        }

        #endregion
    }
}
Was it helpful?

Solution

I found the answer in this article: http://www.c-sharpcorner.com/Forums/Thread/43898/

Selecting the row is not enough, you have to set the CurrentCell to make the row become the CurrentRow. So to make the code above work, you have to change this:

    public void addItem()
    {
        item i = new item(myItems.Count + 1);
        myItems.Add(i);
        foreach (DataGridViewRow dr in dataGridView1.Rows)
        {
            if (dr.DataBoundItem == i)
            {
                dr.Selected = true;
            }
        }
    }

to that:

    public void addItem()
    {
        item i = new item(myItems.Count + 1);
        myItems.Add(i);
        foreach (DataGridViewRow dr in dataGridView1.Rows)
        {
            if (dr.DataBoundItem == i)
            {
                dr.Selected = true;
                dataGridView1.CurrentCell = dr.Cells[0];
            }
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top