Pergunta

Estou preenchendo itens no meu ComboBox de um arquivo XML usando um DataTable. Atualmente, eu tenho o conjunto para que uma coluna seja o membro de exibição do ComboBox e outro é o membro do valor. No entanto, isso nem sempre funciona para mim, pois tenho que definir o parâmetro selecionado e o membro do valor pode não ser único.

Não sei se existe uma duplicata do membro do valor na tabela ou não, então minha ideia era que eu colocaria inteiro Dataarow como o membro do valor do ComboBox e, em seguida, usaria o ComboBox.SelectedItem = (Dataarow) Some_Data_Row; Para selecionar, e sempre selecionava o objeto ComboBox certo.

Como eu conseguiria isso? Existe um jeito melhor de fazer isso? Estou aberto a sugestões, no entanto, é muito importante que eu possa chegar a ambos, exibir membro e membro do valor.

Obrigado pela ajuda!

EDITAR: Talvez eu não estivesse claro o suficiente antes, no entanto, enquanto estou perguntando se essa é a melhor abordagem aqui, também estou perguntando Como as para fazer isso. Se eu não definir o parâmetro ValuEmember, o SelectedItem é do tipo DataRowView ... Observe, que eu quero usar o parâmetro SelectedValue para selecionar itens do ComboBox, e se eu tentar fazer isso sem definir explicitamente o membro do valor e A exceção é lançada.

Foi útil?

Solução 2

Antes de tudo, obrigado Adam Robinson, tenho certeza de que sua resposta estava correta, mas não era o que eu queria ouvir. Eu resolvi meu problema de uma maneira diferente e acho que pode ser útil para outra pessoa, por isso estou postando aqui.

O que fiz foi criado uma nova classe, no meu caso, o nomei ListObject, que tinha uma propriedade DataRow (como você verá mais tarde, ele também funciona para outros tipos, eu apenas usei isso, já que era isso que eu realmente queria como meu item propriedade de valor). Também substitui os métodos:

  • String tostring ()
  • Bool é igual a (objeto obj)
  • int gethashcode () -não é necessário no meu caso, no entanto, o Visual Studio
    avisa que deve ser substituído.

A idéia era que eu pudesse preencher as coleções ComboBox.Items com objetos da minha própria aula, exibir uma string personalizada (se eu não tivesse resolvido assim, minha próxima pergunta no Stack Overflow provavelmente seria sobre personalizar os membros do display ao ler itens de um Dataarow) e compare apenas o item de uma classe (no meu caso Dataarow).

Então, aqui está o código e funciona muito bem (pelo menos pelo que eu queria fazer com ele).

public class ListObject
{
    public DataRow element;

    public String DisplayObject = null;

    public ListObject(DataRow dr)
    {
        element = dr;
    }

    public ListObject(DataRow dr, String dspObject)
    {
        element = dr;
        DisplayObject = dspObject;
    }

    public override String ToString()
    {
        if (DisplayObject == null) throw new Exception("DisplayObject property was not set.");

        return element[DisplayObject].ToString();
    }

    public override bool Equals(object obj)
    {
        if (obj.GetType() == typeof(ListObject))
            return Equals(((ListObject)obj).element, this.element);
        else return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

No meu caso, funciona muito bem, pois posso simplesmente preencher os Combobox's com uma declaração foreach:

dtUsers.ReadXml(Program.Settings.xmlInputUsers);

foreach(DataRow dr in dtUsers.Rows) 
{
    cmbUser.Items.Add(new ListObject(dr, "Name"));
}

E quando eu obtive o DATAROW, quero selecionar, eu só faço isso:

cmbUser.SelectedItem = new ListObject(dlg.SelectedDataRow);

Onde não preciso me preocupar com o membro do visor etc, porque apenas o Datowow será comparado e seus parâmetros de exibição ainda serão definidos quando você preencheu a coleção ComboBox.Items. Além disso, como o método da tostragem é substituído, você pode realmente personalizar sua saída.

Criar esta classe só era possível por causa do artigo do MSDN sobre ComboBox.SelectedItem Propriedade em que foi observado que a propriedade selecionada obra usando o método indexOF. Este método usa o método igual para determinar a igualdade.

Outras dicas

Se você vincular um ListBox para um DataTable, você está realmente vinculando -o a um DataView Isso representa isso DataTable (DataTable implementos IListSource, e isso retorna um DataView). Você não pode definir diretamente SelectedItem para um DataRow exemplo, você tem que defini -lo para um DataRowView instância. Infelizmente, não há maneira fácil de obter um DataRowView a partir de um DataRow.

Você faria melhor apenas fazer todas as suas interações através de um DataRowView. Isso permitirá que você defina SelectedItem explicitamente.

Você não pode usar o SelectedValue propriedade, você deve usar SelectedItem por esta.

Esta é a maneira mais simples de obter o Datatable para um ComboBox

private void load() { 
DataTable dt = // get data from DB 
comboBox1.ValueMember = null; // allows you to get all fields in the obj to combobox
comboBox1.DisplayMember = "ccType";//label displayed from dt
comboBox1.DataSource = dt;
}
//to test 
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {

        DataRowView current = (DataRowView)comboBox1.SelectedValue;
        string drs = current.Row["ID"].ToString();

    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top