Put a combobox on a column of a datagridview

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 columns of the client name, email, date of registration and a combobox with the lists of telephones of each one. These settings are set up 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 the FillDataGrid() function I get the DB data and populate the columns. The problem is when I'm going to add the combobox of phones to the end of the line. The program compiles but loading the form the combo is not mounted and I have the following exception:

IfIremovetheDataGridViewComboBoxCellthelinesaremountedbutthecomboboxisleftwithoutthephones.I'vealsotriedtomountaComboboxandaddittotheendofthedataGridViewClientes.Rows.Add(c.Nome,c.Email,c.DataCadastro,...);linebutIdidnotsucceed.WhereamIgoingwrong?

    
asked by anonymous 08.07.2017 / 04:11

1 answer

2

I followed some tips from a colleague of Stackoverflow in English @JohnG and I was able to do what I wanted. How to put a combobox on datagridview programmatically iterating a Collection . Here is the code I did:

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 DataGridViewTextBoxColumn is already automatically added to the end of the line as if it were already a Combobox . What needs to be done next is to populate the list that DataGridViewTextBoxColumn has. I add the text fields in the int index = dgvClientes.Rows.Add(c.Nome, c.Email, c.DataCadastro); line minus the combobox list. In index , I get what line I am. Then I get the combobox of this line: DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dgvClientes.Rows[index].Cells["Telefones"]; and already fill in the objects in the list.

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 the value property.

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