Solucionado (ver solução)
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