none
Adding Item dynamically into the DataGridViewComboboxColumn

    Question

  • Folks, I need to create a DataGridView where one column should display a Combobox during Editing, and the combobox will have an item "Create New" at the very end of items collection, when user will select this item, I have to popup a dialog and user will write a text on a textbox of that popup dialog, once done, I have to update the cell of the GridValue with that value.

    How can I do this?

    I would appreacite so much if somebody can help me with this.
    Doing stuff with .net
    Tuesday, April 21, 2009 9:20 AM

Answers

  • Hi Moim,

    We need to handle EditingControlShowing event of the DataGridView in such requirement. In the EditingControlShowing event handler, we can get the ComboBox editting control, and add event handler for it.

    I've written the C# code to achieve your goal. To make it easy for you to see the result, you can create a blank Winform(C#) project, and copy the code directly to your form1.cs.


      public partial class Form1 : Form
        {
            private Employee newEmployee = null;
            BindingList <Task> tasks =null;
            BindingList<Employee> emps = null;
            DataGridView dataGridView1 = new DataGridView();
            public Form1()
            {
                InitializeComponent();
                tasks = GetTasks(); // .. implemeted
                emps = GetEmps();// assume i have an implementation
                this.dataGridView1.AutoGenerateColumns = false;
                this.dataGridView1.DataSource = tasks;
                DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
                col1.HeaderText = "TaskName";
                col1.DataPropertyName = "Name";
                this.dataGridView1.Columns.Add(col1);
                DataGridViewComboBoxColumn col2 = new DataGridViewComboBoxColumn();
                col2.HeaderText = "AssignedTo";
                col2.DataPropertyName = "AssignedTo";
                col2.DataSource = emps;
                col2.DisplayMember = "Name";
                col2.ValueMember = "Name";
                this.Controls.Add(dataGridView1);
                this.dataGridView1.Columns.Add(col2);
                this.dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
            }
    
            void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                if (e.Control is ComboBox && this.dataGridView1.CurrentCell.ColumnIndex == 1)
                {
                    ComboBox cb = e.Control as ComboBox;
                    cb.SelectedIndexChanged -= new EventHandler(cb_SelectedIndexChanged);
                    cb.SelectedIndexChanged += new EventHandler(cb_SelectedIndexChanged);
                }
            }
    
            private delegate void setComboBoxSelectedValueDel(Object sender,Object para);
            void cb_SelectedIndexChanged(object sender, EventArgs e)
            {
                ComboBox cb = sender as ComboBox;
                Employee eRef = cb.SelectedItem as Employee;
                    if (eRef !=null && eRef.Name== "Add New Employee")
                    {
                        newEmployee = new Employee();
                        Form2 f = new Form2(newEmployee);
                        f.ShowDialog();
                        //Replace "Add new Item" to newly added Employee name;
                        emps[cb.SelectedIndex].Name = newEmployee.Name;
                        //add the "Add New Employee" record again
                        emps.Add(new Employee("Add New Employee"));
                        //update the selected value of the Current Editing ComboBox.
                        this.BeginInvoke(new setComboBoxSelectedValueDel(SetComboBoxSelectedValue),new object[]{sender,newEmployee.Name});
                    }
              
            }
            void SetComboBoxSelectedValue(Object sender,Object para)
            {
                ComboBox cb = (ComboBox)sender;
                cb.SelectedValue = (string)para;
            }
            BindingList<Task> GetTasks()
            {
                BindingList<Task> list = new BindingList<Task>();
                list.Add(new Task("Job1", "User1"));
                list.Add(new Task("Job2", "User2"));
                return list;
            }
            BindingList<Employee> GetEmps()
            {
                BindingList<Employee> list = new BindingList<Employee>();
                list.Add(new Employee("User1"));
                list.Add(new Employee("User2"));
                list.Add(new Employee("Add New Employee"));
                return list;
            }
    
        }
        class Task
        {
            public string Name { get; set; }
            public String AssignedTo { get; set; }
            public Task()
            {
            }
            public Task(string name, string assignedTo)
            {
                this.Name = name;
                this.AssignedTo = assignedTo;
            }
        }
        class Employee
        {
            public string Name { get; set; }
            public Employee()
            {
            }
            public Employee(string name)
            {
                Name = name;
            }
        }
         class Form2 : Form
        {
            TextBox tb;
            Button btn;
            Employee m_newEmployee;
            void InitializeComponent()
            { 
                tb = new TextBox();
                btn = new Button();
                this.Controls.Add(tb);
                this.Controls.Add(btn);
                btn.Click += new EventHandler(btn_Click);
                btn.Location = new Point(30, 40);
                btn.Text = "OK";
            }
    
            void btn_Click(object sender, EventArgs e)
            {
                this.DialogResult = DialogResult.OK;
                m_newEmployee.Name = this.tb.Text;
            }
            
            public Form2()
            {
                InitializeComponent();
               
            }
            public Form2(Employee newEmployeeName):this()
            {
                m_newEmployee = newEmployeeName;
            }
        }

    If you have any further problem regarding the code or difficulty to understand the detail, please feel free to let me know.


    Bet regards,
    Bruce Zhou
    Please mark the replies as answers if they help and unmark if they don't.
    • Marked as answer by Moim Hossain Wednesday, April 22, 2009 8:07 PM
    Wednesday, April 22, 2009 10:43 AM

All replies

  • ALthough, I noticed, when I select an item from the combobox, next time the selected item doesn't appear into the combobox. as the DataGridView assumes that one-to-one relations. Which is not my case.
    For instance, I have a task lists

    class Task { 
             public string Name {get;set;    
             public Employee AssignedTo { get; set;}
    }
    class Employee
    {
            public string Name { get; set;}
    }
    
    List<Task> tasks = GetTasks(); // .. implemeted
    
    List<Employee> emps = GetEmps();// assume i have an implementation
    

    Now, my grid should display the tasks , as

    Task Name        Assigned To

    -------------------------------------------------

     

    Once I have click onto the assigned to column, it should display a combobox where I will see all the employee names plus an entry "Add new". If I click the last option (add new) then a dialog will allow me to create a new employee into the emploee list and for the next time I will see that new entry available into the combobox.

     

    Guys, can anyone suggest me an approach..? Due to lack of my knowledge, I always find some issues with Grid Controls...so frustrating.. :(

    I would appreciate so much for any response.

     


    Doing stuff with .net
    Tuesday, April 21, 2009 9:47 AM
  • Hi Moim,

    We need to handle EditingControlShowing event of the DataGridView in such requirement. In the EditingControlShowing event handler, we can get the ComboBox editting control, and add event handler for it.

    I've written the C# code to achieve your goal. To make it easy for you to see the result, you can create a blank Winform(C#) project, and copy the code directly to your form1.cs.


      public partial class Form1 : Form
        {
            private Employee newEmployee = null;
            BindingList <Task> tasks =null;
            BindingList<Employee> emps = null;
            DataGridView dataGridView1 = new DataGridView();
            public Form1()
            {
                InitializeComponent();
                tasks = GetTasks(); // .. implemeted
                emps = GetEmps();// assume i have an implementation
                this.dataGridView1.AutoGenerateColumns = false;
                this.dataGridView1.DataSource = tasks;
                DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
                col1.HeaderText = "TaskName";
                col1.DataPropertyName = "Name";
                this.dataGridView1.Columns.Add(col1);
                DataGridViewComboBoxColumn col2 = new DataGridViewComboBoxColumn();
                col2.HeaderText = "AssignedTo";
                col2.DataPropertyName = "AssignedTo";
                col2.DataSource = emps;
                col2.DisplayMember = "Name";
                col2.ValueMember = "Name";
                this.Controls.Add(dataGridView1);
                this.dataGridView1.Columns.Add(col2);
                this.dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
            }
    
            void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                if (e.Control is ComboBox && this.dataGridView1.CurrentCell.ColumnIndex == 1)
                {
                    ComboBox cb = e.Control as ComboBox;
                    cb.SelectedIndexChanged -= new EventHandler(cb_SelectedIndexChanged);
                    cb.SelectedIndexChanged += new EventHandler(cb_SelectedIndexChanged);
                }
            }
    
            private delegate void setComboBoxSelectedValueDel(Object sender,Object para);
            void cb_SelectedIndexChanged(object sender, EventArgs e)
            {
                ComboBox cb = sender as ComboBox;
                Employee eRef = cb.SelectedItem as Employee;
                    if (eRef !=null && eRef.Name== "Add New Employee")
                    {
                        newEmployee = new Employee();
                        Form2 f = new Form2(newEmployee);
                        f.ShowDialog();
                        //Replace "Add new Item" to newly added Employee name;
                        emps[cb.SelectedIndex].Name = newEmployee.Name;
                        //add the "Add New Employee" record again
                        emps.Add(new Employee("Add New Employee"));
                        //update the selected value of the Current Editing ComboBox.
                        this.BeginInvoke(new setComboBoxSelectedValueDel(SetComboBoxSelectedValue),new object[]{sender,newEmployee.Name});
                    }
              
            }
            void SetComboBoxSelectedValue(Object sender,Object para)
            {
                ComboBox cb = (ComboBox)sender;
                cb.SelectedValue = (string)para;
            }
            BindingList<Task> GetTasks()
            {
                BindingList<Task> list = new BindingList<Task>();
                list.Add(new Task("Job1", "User1"));
                list.Add(new Task("Job2", "User2"));
                return list;
            }
            BindingList<Employee> GetEmps()
            {
                BindingList<Employee> list = new BindingList<Employee>();
                list.Add(new Employee("User1"));
                list.Add(new Employee("User2"));
                list.Add(new Employee("Add New Employee"));
                return list;
            }
    
        }
        class Task
        {
            public string Name { get; set; }
            public String AssignedTo { get; set; }
            public Task()
            {
            }
            public Task(string name, string assignedTo)
            {
                this.Name = name;
                this.AssignedTo = assignedTo;
            }
        }
        class Employee
        {
            public string Name { get; set; }
            public Employee()
            {
            }
            public Employee(string name)
            {
                Name = name;
            }
        }
         class Form2 : Form
        {
            TextBox tb;
            Button btn;
            Employee m_newEmployee;
            void InitializeComponent()
            { 
                tb = new TextBox();
                btn = new Button();
                this.Controls.Add(tb);
                this.Controls.Add(btn);
                btn.Click += new EventHandler(btn_Click);
                btn.Location = new Point(30, 40);
                btn.Text = "OK";
            }
    
            void btn_Click(object sender, EventArgs e)
            {
                this.DialogResult = DialogResult.OK;
                m_newEmployee.Name = this.tb.Text;
            }
            
            public Form2()
            {
                InitializeComponent();
               
            }
            public Form2(Employee newEmployeeName):this()
            {
                m_newEmployee = newEmployeeName;
            }
        }

    If you have any further problem regarding the code or difficulty to understand the detail, please feel free to let me know.


    Bet regards,
    Bruce Zhou
    Please mark the replies as answers if they help and unmark if they don't.
    • Marked as answer by Moim Hossain Wednesday, April 22, 2009 8:07 PM
    Wednesday, April 22, 2009 10:43 AM
  • Thanks Bruce, I was able to resolve this ..and I did exactly what you said here. Thanks a lot for ur reply Buddy! 
    - Moim Hossain [Please mark as answer if this post helps you]
    Wednesday, April 22, 2009 8:09 PM
  • Brillliant, Bruce, thank you so  much.  I've been looking for a solution to this problem for three days.

    I am curious about a couple of things I don't understand in your code, though.

     

    In the 'EditingCntrolShowing' Event, why do you remove and then re-add the handler?  (to force another event, perhaps?)

    I also don't fully understand the AssignedTo and binding, and why it is required.

     

    Thanks.

     

     

     

    Wednesday, January 19, 2011 9:32 PM