首页 > 解决方案 > c# Populate datagridview based on ComboBox Item Selected

问题描述

I have this datagrid where Combobox is populated from Db.

What I'm trying to achieve is that when I select something in the column "Esercizio", the cell of "Video" column auto populate with respective value from the "link_video" column of Db.

So if I select "kickback", I need to see the link video of kickback from db in the textbox cell.

Here's the code that i use to populate the combobox on form load:

private void Myform_Load(object sender, EventArgs e) {

        con = new SqlConnection("Data Source=(LocalDB)\\etc");
        cmd = new SqlCommand();
        con.Open();
        cmd.Connection = con;
        cmd.CommandText = "SELECT * FROM Esercizi";
        dr = cmd.ExecuteReader();

        while (dr.Read())
        {
          //populate Column1 combobox with "nome" column from Esercizi db table
            Column1.Items.Add(dr["nome"]);
            
        }

        con.Close();
    }

datagridview

EDIT I've figured out with 2 new problems.

I'm trying to load a saved workout from db but when I do this, no video link populate the dgv as the grid event doesn't fire.

What I've tried is to add a foreach loop to a new selectionindexchanged function and to fire it at the end of the Load Button code like this:

private void curCombo_LoadedValues(object sender, EventArgs e)
        {

            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                foreach (DataGridViewCell cell in row.Cells)
                {
                    if (curCombo != null && curCombo.SelectedValue != null)
                    {
                        ExerciseAndVideo selectedExercise = (ExerciseAndVideo)curCombo.SelectedItem;
                        dataGridView1.CurrentRow.Cells["Video"].Value = selectedExercise.Video;

                    }
                }
            }
        }

private void button9_Click(object sender, EventArgs e){

    string connectionString = "Data Source=(LocalDB)\\etc";
    string sql = "SELECT * FROM Schede WHERE Id = 6 AND dgv = 'dataGridView1'";
    SqlConnection connection = new SqlConnection(connectionString);
    SqlDataAdapter dataadapter = new SqlDataAdapter(sql, connection);using (DataTable dt = new DataTable())
    {
        dataadapter.Fill(dt);

        //Set AutoGenerateColumns False
        dataGridView1.AutoGenerateColumns = false;

        //Set Columns Count
        dataGridView1.ColumnCount = 6;

        //Add Columns

        dataGridView1.Columns[0].Name = "Esercizio";
        dataGridView1.Columns[0].HeaderText = "Esercizio";
        dataGridView1.Columns[0].DataPropertyName = "Esercizio";

        dataGridView1.Columns[1].Name = "Serie";
        dataGridView1.Columns[1].HeaderText = "Serie";
        dataGridView1.Columns[1].DataPropertyName = "Serie";

        dataGridView1.Columns[2].HeaderText = "Ripetizioni";
        dataGridView1.Columns[2].Name = "Ripetizioni";
        dataGridView1.Columns[2].DataPropertyName = "Ripetizioni";

        dataGridView1.Columns[3].Name = "Recupero";
        dataGridView1.Columns[3].HeaderText = "Recupero";
        dataGridView1.Columns[3].DataPropertyName = "Recupero";

        dataGridView1.Columns[4].Name = "Time Under Tension";
        dataGridView1.Columns[4].HeaderText = "Time Under Tension";
        dataGridView1.Columns[4].DataPropertyName = "Time_Under_Tension";

        dataGridView1.DataSource = dt;

        connection.Close();

        
    }

    curCombo_LoadedValues();
}

But I get this error "the are no arguments for the obligatory parameter sender...

How I can call it correctly?

The second Issue is that when I populate some dgv columns like this, combos stops working correctly and I get an error exception on the combobox :

dataGridView1.Rows.Add(7);
            Random rnd = new Random();
            
            dataGridView1.Rows[0].Cells[1].Value = 3;
            dataGridView1.Rows[0].Cells[2].Value = rnd.Next(1, 13);
            dataGridView1.Rows[0].Cells[3].Value = 1;
            dataGridView1.Rows[0].Cells[4].Value = 201;
            
            dataGridView1.Rows[1].Cells[1].Value = 2;
            dataGridView1.Rows[1].Cells[2].Value = rnd.Next(1, 13);
            dataGridView1.Rows[1].Cells[3].Value = 1;
            dataGridView1.Rows[1].Cells[4].Value = 201;
            
            dataGridView1.Rows[2].Cells[1].Value = 3;
            dataGridView1.Rows[2].Cells[2].Value = rnd.Next(1, 13);
            dataGridView1.Rows[2].Cells[3].Value = 1;
            dataGridView1.Rows[2].Cells[4].Value = 201;
            
            dataGridView1.Rows[3].Cells[1].Value = 4;
            dataGridView1.Rows[3].Cells[2].Value = rnd.Next(1, 13);
            dataGridView1.Rows[3].Cells[3].Value = 1;
            dataGridView1.Rows[3].Cells[4].Value = 201;
            
            dataGridView1.Rows[4].Cells[1].Value = 5;
            dataGridView1.Rows[4].Cells[2].Value = rnd.Next(1, 13);
            dataGridView1.Rows[4].Cells[3].Value = 1;
            dataGridView1.Rows[4].Cells[4].Value = 201;
            
            dataGridView1.Rows[5].Cells[1].Value = 6;
            dataGridView1.Rows[5].Cells[2].Value = rnd.Next(1, 13);
            dataGridView1.Rows[5].Cells[3].Value = 1;
            dataGridView1.Rows[5].Cells[4].Value = 201;
            
            dataGridView1.Rows[6].Cells[1].Value = 7;
            dataGridView1.Rows[6].Cells[2].Value = rnd.Next(1, 13);
            dataGridView1.Rows[6].Cells[3].Value = 1;
            dataGridView1.Rows[6].Cells[4].Value = 201;

This is the look of the dgv now: dgv

And this is the error the i get after combos stop working correctly (I click and no dropdown appear or if I click 2-3 times, a random item get selected but no video link appear in the other column):

error

标签: c#datagridviewdatagridviewcomboboxcell

解决方案


I mixed ComboBox with DatagridViewComboboxColumn. It's partly your fault :).

Here you have a form with events. Since CellValueChanged fires on cell exit, I added a Dirty StateEvent to update the Video column. From the designer, just put the datagrid in the form and make sure the name is the same. IMHO, these 3 events are crucial

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

            Init();
        }

        private void Init()
        {
            var list = new List<Exercise>() {
            new Exercise (){Name="Name1", Link= "Link1" },
            new Exercise (){Name="Name3", Link= "Link3" },
            new Exercise (){Name="Name4", Link= "Link4" },

            };

            var comboColumn = new DataGridViewComboBoxColumn() { Name = "ExerciseName", CellTemplate = new DataGridViewComboBoxCell() };
            comboColumn.DisplayMember = nameof(Exercise.Name);
            comboColumn.ValueMember = nameof(Exercise.Link);
            comboColumn.DataSource = list;
            
            dataGridView1.Columns.Add(comboColumn);
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn() { Name = "Video" });
            dataGridView1.CellContentClick += DataGridView1_CellContentClick;
            dataGridView1.CellValueChanged += DataGridView1_CellValueChanged;
            dataGridView1.CurrentCellDirtyStateChanged += DataGridView1_CurrentCellDirtyStateChanged;
        }

        private void DataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            var currentCell = (sender as DataGridView).CurrentCell;
            if(currentCell.ColumnIndex == 0)
                dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
            
        }

        private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex != 0)
                return;
            var comboCell = (dataGridView1.Rows[e.RowIndex].Cells[0] as DataGridViewComboBoxCell);
            var value = comboCell.Value;
            dataGridView1.Rows[e.RowIndex].Cells["Video"].Value = value;

        }

        private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            
        }
    }

    public class Exercise
    {
        public string Name { get; set; }
        public string Link { get; set; }
    }

推荐阅读