Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
10
respostas

Como fazer com que o combo box retorne uma propriedade do meu objeto

Tenho um array chamado cliente. Não consegui colocar em prática a ideia de passar um objeto ao combo box pra ficar mais fácil retornar o valor depois. Eu tentei o seguinte:

foreach (Clientes cl in cliente)
{
      comboClientes.Items.Add(cl);
}
comboClientes.DisplayMember = "nome";

Preciso que ele adicione a propriedade nome de cada uma das minhas posições do array.

Pelo que eu sei, depois posso retornar a referência do item selecionado assim:

Clientes selecao = (Clientes)comboClientes.SelectedItem;

Estou certo?

10 respostas

Oi Marcelo

Você está certo sim. Poste o código do formulário que você está usando e o código da sua classe Clientes.

/* Talvez esteja certo até ai. Minha criação de clientes deu certo mas na hora de exibir eles no combo box só aparece o nome de cada objeto, quando eu seleciono um dá exceção obviamente. Aparece Caelum.Clientes.CaixaEletronico.Clientes em vez do nome de cada cliente

Aonde está o erro? */

//Código que cadastra clientes:

if (this.qtContas == 0) { this.cliente = new Clientes[1]; //se não houver clientes cadastrados este trecho cria o array de uma posição. } else { Array.Resize(ref this.cliente, (qtContas + 1)); //se já houver, aumenta em mais um o número de posições no array. }

//daqui pra baixo é a inclusão dos dados preenchidos no formulário ao array.

this.cliente[this.qtContas] = new Clientes(nome, idade, new Contas()); this.cliente[this.qtContas].conta.numero = (this.qtContas + 1); this.cliente[this.qtContas].conta.Depositar(saldo); this.qtContas++;

Oi Marcelo

É realmente difícil de lhe ajudar quando você posta trechos de código que não podem ser replicados localmente.

Por favor, poste o código completo da sua classe Clientes e do formulário, inclua inclusive os using no começo do arquivo.

É até melhor, o outro eu endentei errado.

O meu programa não tem ContaCorrente e nem ContaPoupanca.

Classe Principal (é a equivalente a Form1):

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 Caelum.CaixaEletronico
{
    public partial class Principal : Form
    {
        private Clientes[] cliente;
        private int qtContas = 0;
        public Principal()
        {
            InitializeComponent();
            MostraConta();
        }
        public void MostraConta()
        {
            if (qtContas != 0)
            {
                mensagem.Text = "";
                comboClientes.Enabled = true;
                TextoValor.Enabled = true;
                botaoDepositar.Enabled = true;
                botaoSaque.Enabled = true;

                foreach (Clientes cl in cliente)
                {
                    comboClientes.Items.Add(cl);
                }
                comboClientes.DisplayMember = "nome";

            }
            else
            {
                mensagem.Text = "Não há contas cadastradas.";
                comboClientes.Enabled = false;
                TextoValor.Enabled = false;
                botaoDepositar.Enabled = false;
                botaoSaque.Enabled = false;
            }
        }

        private void botaoSaque_Click(object sender, EventArgs e)
        {
            if (TextoValor.Text !="")
            {
                try
                {
                    Contas selecionado = (Contas)comboClientes.SelectedItem;
                    selecionado.Sacar(Convert.ToDouble(TextoValor.Text));
                    TextoValor.Text = "";
                    MostraConta();
                }
                catch (SaldoInsuficienteException exception)
                {
                    MessageBox.Show("Saldo Insuficiente.");
                }
                catch (ArgumentException exception)
                {
                    MessageBox.Show("Valor inválido para o saque.");
                }
                TextoValor.Text = "";
            }
        }

        private void botaoDepositar_Click(object sender, EventArgs e)
        {
            if (TextoValor.Text != "")
            {
                try
                {
                    Contas selecionado = (Contas)comboClientes.SelectedItem;
                selecionado.Depositar(Convert.ToDouble(TextoValor.Text));
                TextoValor.Text = "";
                MostraConta();
                }
                catch (ArgumentException exception)
                {
                    MessageBox.Show("Valor inválido para o saque.");
                }
            }
        }

        private void comboClientes_SelectedIndexChanged(object sender, EventArgs e)
        {
            Contas selecionado = (Contas)comboClientes.SelectedItem;
            textoNumeroConta.Text = Convert.ToString(selecionado.numero);
            TextoSaldo.Text = Convert.ToString(selecionado.Saldo);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CadastroContas cadastro = new CadastroContas(this);
            cadastro.ShowDialog();
        }
        public void CadastrarConta(string nome, int idade, double saldo)
        {
            if (this.qtContas == 0)
            {
                this.cliente = new Clientes[1];
            }
            else
            {
                Array.Resize(ref this.cliente, (qtContas + 1));
            }
            this.cliente[this.qtContas] = new Clientes(nome, idade, new Contas());
            this.cliente[this.qtContas].conta.numero = (this.qtContas + 1);
            this.cliente[this.qtContas].conta.Depositar(saldo);
            this.qtContas++;
        }
    }
}

Classe Clientes:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caelum.CaixaEletronico
{
    public class Clientes
    {
        public int idade;
        public string nome;
        public Contas conta;

        public Clientes(string nome, int idade, Contas conta)
        {
            this.conta = conta;
            this.nome = nome;
            this.idade = idade;
        }
    }
}

Classe Contas:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Caelum.CaixaEletronico
{
    public class Contas
    {
        public int numero;
        public double Saldo { get; protected set; }

        public void Sacar(double valor)
        {
            if (valor <= 0)
            {
                throw new ArgumentException();
            }
            if (this.Saldo >= valor)
            {
                this.Saldo -= valor;
            }
            else
            {
                throw new SaldoInsuficienteException();
            }
        }
        public void Depositar(double valor)
        {
            if (valor <= 0)
            {
                throw new ArgumentException();
            }
            else
            {
                this.Saldo += valor;
            }
        }
    }
}

Classe CadastroContas:

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 Caelum.CaixaEletronico
{
    public partial class CadastroContas : Form
    {
        private Principal aplicacaoPrincipal;
        public CadastroContas(Principal principal)
        {
            InitializeComponent();
            this.aplicacaoPrincipal = principal;
        }

        private void Cadastro_Click(object sender, EventArgs e)
        {
            if (textoNome.Text != "" &&
                textoIdade.Text != "" &&
                textoSaldo.Text != "")
            {
                aplicacaoPrincipal.CadastrarConta(textoNome.Text,
                    Convert.ToInt32(textoIdade.Text),
                    Convert.ToDouble(textoSaldo.Text));

                MessageBox.Show("Cadastro Efetuado.");
                aplicacaoPrincipal.MostraConta();
                this.Close();
            }
            else
            {
                MessageBox.Show("Para efetuar o cadastro é necessário\npreencher todos os campos.");
            }
        }

        private void Fechar_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

Se quiser, aqui está a inicialização dos componentes.

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 Caelum.CaixaEletronico
{
    public partial class Principal : Form
    {
        private Clientes[] cliente;
        private int qtContas = 0;
        public Principal()
        {
            InitializeComponent();
            MostraConta();
        }
        public void MostraConta()
        {
            if (qtContas != 0)
            {
                mensagem.Text = "";
                comboClientes.Enabled = true;
                TextoValor.Enabled = true;
                botaoDepositar.Enabled = true;
                botaoSaque.Enabled = true;

                foreach (Clientes cl in cliente)
                {
                    comboClientes.Items.Add(cl);
                }
                comboClientes.DisplayMember = "nome";

            }
            else
            {
                mensagem.Text = "Não há contas cadastradas.";
                comboClientes.Enabled = false;
                TextoValor.Enabled = false;
                botaoDepositar.Enabled = false;
                botaoSaque.Enabled = false;
            }
        }

        private void botaoSaque_Click(object sender, EventArgs e)
        {
            if (TextoValor.Text !="")
            {
                try
                {
                    Contas selecionado = (Contas)comboClientes.SelectedItem;
                    selecionado.Sacar(Convert.ToDouble(TextoValor.Text));
                    TextoValor.Text = "";
                    MostraConta();
                }
                catch (SaldoInsuficienteException exception)
                {
                    MessageBox.Show("Saldo Insuficiente.");
                }
                catch (ArgumentException exception)
                {
                    MessageBox.Show("Valor inválido para o saque.");
                }
                TextoValor.Text = "";
            }
        }

        private void botaoDepositar_Click(object sender, EventArgs e)
        {
            if (TextoValor.Text != "")
            {
                try
                {
                    Contas selecionado = (Contas)comboClientes.SelectedItem;
                selecionado.Depositar(Convert.ToDouble(TextoValor.Text));
                TextoValor.Text = "";
                MostraConta();
                }
                catch (ArgumentException exception)
                {
                    MessageBox.Show("Valor inválido para o saque.");
                }
            }
        }

        private void comboClientes_SelectedIndexChanged(object sender, EventArgs e)
        {
            Contas selecionado = (Contas)comboClientes.SelectedItem;
            textoNumeroConta.Text = Convert.ToString(selecionado.numero);
            TextoSaldo.Text = Convert.ToString(selecionado.Saldo);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CadastroContas cadastro = new CadastroContas(this);
            cadastro.ShowDialog();
        }
        public void CadastrarConta(string nome, int idade, double saldo)
        {
            if (this.qtContas == 0)
            {
                this.cliente = new Clientes[1];
            }
            else
            {
                Array.Resize(ref this.cliente, (qtContas + 1));
            }
            this.cliente[this.qtContas] = new Clientes(nome, idade, new Contas());
            this.cliente[this.qtContas].conta.numero = (this.qtContas + 1);
            this.cliente[this.qtContas].conta.Depositar(saldo);
            this.qtContas++;
        }
    }
}
namespace Caelum.CaixaEletronico
{
    partial class Principal
    {
        /// <summary>
        /// Variável de designer necessária.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Limpar os recursos que estão sendo usados.
        /// </summary>
        /// <param name="disposing">verdade se for necessário descartar os recursos gerenciados; caso contrário, falso.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region código gerado pelo Windows Form Designer

        /// <summary>
        /// Método necessário para suporte do Designer - não modifique
        /// o conteúdo deste método com o editor de código.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.textoNumeroConta = new System.Windows.Forms.TextBox();
            this.TextoSaldo = new System.Windows.Forms.TextBox();
            this.label4 = new System.Windows.Forms.Label();
            this.TextoValor = new System.Windows.Forms.TextBox();
            this.botaoSaque = new System.Windows.Forms.Button();
            this.botaoDepositar = new System.Windows.Forms.Button();
            this.button1 = new System.Windows.Forms.Button();
            this.comboClientes = new System.Windows.Forms.ComboBox();
            this.mensagem = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(42, 61);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(92, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Número da conta:";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(42, 15);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(39, 13);
            this.label2.TabIndex = 1;
            this.label2.Text = "Titular:";
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(42, 93);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(37, 13);
            this.label3.TabIndex = 2;
            this.label3.Text = "Saldo:";
            // 
            // textoNumeroConta
            // 
            this.textoNumeroConta.Location = new System.Drawing.Point(140, 58);
            this.textoNumeroConta.Name = "textoNumeroConta";
            this.textoNumeroConta.ReadOnly = true;
            this.textoNumeroConta.Size = new System.Drawing.Size(121, 20);
            this.textoNumeroConta.TabIndex = 3;
            // 
            // TextoSaldo
            // 
            this.TextoSaldo.Location = new System.Drawing.Point(140, 93);
            this.TextoSaldo.Name = "TextoSaldo";
            this.TextoSaldo.ReadOnly = true;
            this.TextoSaldo.Size = new System.Drawing.Size(121, 20);
            this.TextoSaldo.TabIndex = 5;
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(42, 161);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(34, 13);
            this.label4.TabIndex = 6;
            this.label4.Text = "Valor:";
            // 
            // TextoValor
            // 
            this.TextoValor.Location = new System.Drawing.Point(140, 158);
            this.TextoValor.Name = "TextoValor";
            this.TextoValor.Size = new System.Drawing.Size(121, 20);
            this.TextoValor.TabIndex = 7;
            // 
            // botaoSaque
            // 
            this.botaoSaque.Location = new System.Drawing.Point(12, 226);
            this.botaoSaque.Name = "botaoSaque";
            this.botaoSaque.Size = new System.Drawing.Size(75, 23);
            this.botaoSaque.TabIndex = 8;
            this.botaoSaque.Text = "Sacar";
            this.botaoSaque.UseVisualStyleBackColor = true;
            this.botaoSaque.Click += new System.EventHandler(this.botaoSaque_Click);
            // 
            // botaoDepositar
            // 
            this.botaoDepositar.Location = new System.Drawing.Point(93, 226);
            this.botaoDepositar.Name = "botaoDepositar";
            this.botaoDepositar.Size = new System.Drawing.Size(75, 23);
            this.botaoDepositar.TabIndex = 9;
            this.botaoDepositar.Text = "Depositar";
            this.botaoDepositar.UseVisualStyleBackColor = true;
            this.botaoDepositar.Click += new System.EventHandler(this.botaoDepositar_Click);
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(174, 226);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(98, 23);
            this.button1.TabIndex = 10;
            this.button1.Text = "Crar nova Conta";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // comboClientes
            // 
            this.comboClientes.FormattingEnabled = true;
            this.comboClientes.Location = new System.Drawing.Point(12, 15);
            this.comboClientes.Name = "comboClientes";
            this.comboClientes.Size = new System.Drawing.Size(249, 21);
            this.comboClientes.TabIndex = 11;
            this.comboClientes.SelectedIndexChanged += new System.EventHandler(this.comboClientes_SelectedIndexChanged);
            // 
            // mensagem
            // 
            this.mensagem.AutoSize = true;
            this.mensagem.Location = new System.Drawing.Point(65, 130);
            this.mensagem.Name = "mensagem";
            this.mensagem.Size = new System.Drawing.Size(59, 13);
            this.mensagem.TabIndex = 12;
            this.mensagem.Text = "Mensagem";
            this.mensagem.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // Principal
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 261);
            this.Controls.Add(this.mensagem);
            this.Controls.Add(this.comboClientes);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.botaoDepositar);
            this.Controls.Add(this.botaoSaque);
            this.Controls.Add(this.TextoValor);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.TextoSaldo);
            this.Controls.Add(this.textoNumeroConta);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Name = "Principal";
            this.Text = "Caixa Eletrônico";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.TextBox textoNumeroConta;
        private System.Windows.Forms.TextBox TextoSaldo;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox TextoValor;
        private System.Windows.Forms.Button botaoSaque;
        private System.Windows.Forms.Button botaoDepositar;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.ComboBox comboClientes;
        private System.Windows.Forms.Label mensagem;
    }
}

OI Marcelo

O problema é que o DisplayMember do combo box trabalha com propriedades declaradas na classe e não com atributos.

Para fazer seu código funcionar, você precisa declarar propriedades na classe Clientes ao invés de atributos

public class Clientes
{
    public int Idade { get; set; }

    public string Nome { get; set; }

    public Contas Conta { get; set; }
}

Lembrando que a convenção de nome da propriedade é o pascal casing (primeira letra em maiúscula), além disso, reparei que no seu código o nome das classes está no plural, mas isso deixa o seu código estranho de ler, afinal Clientes representa o modelo de um Cliente.

Nunca ia descobrir. Valeu.

Mas agora o código não dá exceção mas faz um erro. Ao cadastrar 2 itens o primeiro é duplicado. Se eu cadastrar Marcelo e Pedro, o combo box mostra assim:

Marcelo
Marcelo
Pedro

Porque isso acontece?

Só pra constar, eu consertei outro erro:

private void comboCliente_SelectedIndexChanged(object sender, EventArgs e)
        {
            Cliente selecionado = (Cliente)comboClientes.SelectedItem;
            textoNumeroConta.Text = Convert.ToString(selecionado.Conta.numero);
            TextoSaldo.Text = Convert.ToString(selecionado.Conta.Saldo);
        }

Eu usei Clientes e Contas pra eu entender melhor a diferença do tipo Clientes ou Contas com a variável que carrega o objeto criado. Mas agora eu vou mudar pra Cliente e Conta

solução!

Oi Marcelo

Esse segundo erro acontece por causa do foreach que você colocou dentro do método MostraConta

foreach (Clientes cl in cliente)
{
    comboClientes.Items.Add(cl);
}

Quando você cadastra a primeira Conta o foreach é executado e o ComboBox recebe um item.

No cadastro da segunda conta, o combo box já tem um item e você executa o foreach novamente, com isso a primeira e a segunda conta são adicionados e por isso você está tendo esse resultado estranho.

Para corrigir o problema, você pode pensar em como você poderia reescrever o código do seu método MostraConta sem depender do foreach ou limpar os itens do combo box antes do foreach:

comboClientes.Items.Clear();

Valeu mesmo. Resolveu meu programa