Place a combobox in a datagridview column

Asked

Viewed 1,356 times

1

Using C#, with Entityframework and codefirst, I have the following classes in my models layer:

public class Cliente
{
    public int ClienteId { get; set; }
    public string Nome { get; set; }
    public string Email { get; set; }
    public DateTime DataCadastro { get; set; }
    public bool Ativo { get; set; }

    public virtual ICollection<Endereco> Enderecos { get; set; }
    public virtual ICollection<Telefone> Telefones { get; set; }
}

    public class Endereco
    {
        public int EnderecoId { get; set; }
        public string Cep { get; set; }
        public string Rua { get; set; }
        public string Numero { get; set; }
        public string Complemento { get; set; }
        public string Bairro { get; set; }
        public string Cidade { get; set; }
        public string Estado { get; set; }
        public decimal TaxaDeEntrega { get; set; }

        public int ClienteId { get; set; }
        public virtual  Cliente Cliente { get; set; }
    }

    public class Telefone
    {
        public int TelefoneId { get; set; }
        public string Numero { get; set; }
        public int ClienteID { get; set; }

        public virtual Cliente Cliente { get; set; }
    }

In my Forms layer, I have a form with a datagridview with the customer name columns, email, registration date and a combobox with the phone lists of each one. These settings are mounted as follows:

private void FormClientes_Load(object sender, EventArgs e)
        {
            //Não exibe os ícones de Maximixação e minimização do form dentro de uma MDI Parent
            this.FormBorderStyle = FormBorderStyle.None;
            this.ControlBox = false;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.ShowIcon = false;
            this.Dock = DockStyle.Fill;

            dataGridViewClientes.AutoGenerateColumns = false;
            dataGridViewClientes.RowHeadersVisible = false;//Omite a primeira coluna

            DataGridViewTextBoxColumn colNome = new DataGridViewTextBoxColumn();
            colNome.HeaderText = "NOME";
            colNome.DataPropertyName = "Nome";
            dataGridViewClientes.Columns.Add(colNome);

            DataGridViewTextBoxColumn colEmail = new DataGridViewTextBoxColumn();
            colEmail.HeaderText = "EMAIL";
            colEmail.DataPropertyName = "Email";
            dataGridViewClientes.Columns.Add(colEmail);

            DataGridViewTextBoxColumn colDataCadastro = new DataGridViewTextBoxColumn();
            colDataCadastro.HeaderText = "DATA CADASTRO";
            colDataCadastro.DataPropertyName = "DataCadastro";
            dataGridViewClientes.Columns.Add(colDataCadastro);

            DataGridViewComboBoxColumn colTelefones = new DataGridViewComboBoxColumn();
            colTelefones.HeaderText = "TELEFONES";
            colTelefones.DataPropertyName = "Numero";
            dataGridViewClientes.Columns.Add(colTelefones);

            FillDataGrid();
        }

        private void FillDataGrid()
        {
            foreach (var c in _clienteApp.GetAll())
            {
                DataGridViewComboBoxCell cbc = new DataGridViewComboBoxCell();

                foreach (var t in c.Telefones)
                {
                    cbc.Items.Add(t.Numero);
                }

                dataGridViewClientes.Rows.Add(c.Nome, c.Email, c.DataCadastro, cbc);
            }
        }

In function FillDataGrid() I take the data from the BD and populate the columns. The problem is when I will add the phone combobox to the end of the row. The program compiles but when loading the form a combo is not mounted and I have the following Exception:

inserir a descrição da imagem aqui

If I remove the DataGridViewComboBoxCell the lines are mounted but the combobox is without the phones. I have also tried to mount a Combobox and add it to the end of the line dataGridViewClientes.Rows.Add(c.Nome, c.Email, c.DataCadastro, ... ); but I didn’t succeed. Where I’m going wrong ? inserir a descrição da imagem aqui

1 answer

2


I followed some tips from a colleague of Stackoverflow in English @Johng and managed to do what I wanted. How to put a combobox on datagridview programmatically iterating a Collection. Below follows the code I made:

private void FillDataGrid()
        {
            ConfiguraPaginacao();

            dgvClientes.Rows.Clear();
            dgvClientes.Columns.Clear();

            var colNome = new DataGridViewTextBoxColumn();
            colNome.HeaderText = "NOME";
            colNome.DataPropertyName = "Nome";
            colNome.SortMode = DataGridViewColumnSortMode.Automatic;

            var colEmail = new DataGridViewTextBoxColumn();
            colEmail.HeaderText = "EMAIL";
            colEmail.DataPropertyName = "Email";
            colEmail.SortMode = DataGridViewColumnSortMode.Automatic;

            var colDataCadastro = new DataGridViewTextBoxColumn();
            colDataCadastro.HeaderText = "DATA CADASTRO";
            colDataCadastro.DataPropertyName = "DataCadastro";
            colDataCadastro.SortMode = DataGridViewColumnSortMode.Automatic;

            var colTelefones = new DataGridViewComboBoxColumn();
            colTelefones.HeaderText = "TELEFONES";
            colTelefones.DataPropertyName = "Numero";
            colTelefones.Name = "Telefones";
            colTelefones.SortMode = DataGridViewColumnSortMode.Automatic;

            dgvClientes.Columns.Add(colNome);
            dgvClientes.Columns.Add(colEmail);
            dgvClientes.Columns.Add(colDataCadastro);
            dgvClientes.Columns.Add(colTelefones);

            foreach (var c in _clienteApp.GetAllToPagination(paginaAtual, itensPorPagina).ToList())
            {
                int index = dgvClientes.Rows.Add(c.Nome, c.Email, c.DataCadastro);

                DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dgvClientes.Rows[index].Cells["Telefones"];
                cb.DataSource = c.Telefones.ToList();
                cb.ValueMember = "Numero";
                cb.DisplayMember = "Numero";

                //Exibe o primeiro número de telefone na combobox
                if (c.Telefones.Count > 0)
                    cb.Value = c.Telefones.First().Numero.ToString();
            }

            dgvClientes.Sort(dgvClientes.Columns[2], ListSortDirection.Descending);
        }

After studying better, I noticed that the DataGridViewTextBoxColumn is already automatically added to the end of the line as if it were already a Combobox. What needs to be done later is to fill in the list that the DataGridViewTextBoxColumn has. I add the text fields on the line int index = dgvClientes.Rows.Add(c.Nome, c.Email, c.DataCadastro); minus the combobox list. In index, I pick up which line I am. Then I pick up the combobox of that line: DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dgvClientes.Rows[index].Cells["Telefones"]; and I already fill in the list objects.

cb.DataSource = c.Telefones.ToList();
                cb.ValueMember = "Numero";
                cb.DisplayMember = "Numero";

Another cool tip is that to keep selected the first item of DataGridViewComboBoxCell , I only have property value.

//Exibe o primeiro número de telefone na combobox
if (c.Telefones.Count > 0){
   cb.Value = c.Telefones.First().Numero.ToString();
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.