Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Cargar Combobox Manualmente + un Identificador (https://www.clubdelphi.com/foros/showthread.php?t=84433)

ginkaku 18-10-2013 07:39:02

Cargar Combobox Manualmente + un Identificador
 
Buenas como estan gente? Estoy programando mediante clases y objetos, y tengo una clase que me devuelve una lista de string lista para que yo luego los añada a un combobox o un comboboxEx. Hasta aqui todo bien, corre, ahora tambien deseo asignar un valor/identificador o como gusten llamarlo al item,no para mostrarlo al mismo tiempo sino para q yo lo maneje internamente, por ejemplo:
Código:

ComboBoxEx1->ItemsEx->Add();
ComboBoxEx1->ItemsEx->operator [](0)->Caption = "Juan";
ComboBoxEx1->ItemsEx->operator [](0)->valor/id = 101; //  <---------esta demas recalcar que esto es lo q pretendo hacer
ComboBoxEx1->ItemsEx->Add();
ComboBoxEx1->ItemsEx->operator [](1)->Caption = "Pedro";
ComboBoxEx1->ItemsEx->operator [](1)->valor/id = 230;

Algo asi me gustaria hacer, para que mas adelante utilice el valor del item seleccionado. Lo que pasa es que no puedo usar dbcontrols por motivos de solicitud. Yo usaba los JFCONTROLS donde su jfcombobox me permitia hacer esto perfectamente,pero ahora solo tengo el embarcadero XE5 y no logro instalar mi jfcontrols. Pero bueno la idea es esa, que se despliegue el combo normalmente y de acuerdo a lo seleccionado obtenga su valor asignado. Muchas gracias de antemano
PDT: Nunca tengo el delphi a mano asi que disculpen solo tengo c++ en la portatil

ecfisa 18-10-2013 10:24:02

Hola ginkaku.

Te pongo un ejemplo de como cargar en un TComboBox desde un TDataSet el campo "NOMBRE" de tipo alfanumérico y el campo "ID" de tipo entero. El primer campo se visualiza en el ComboBox y en el evento OnChange de este, se obtiene el valor del campo "ID" correspondiente.

Código:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  DataSet->DisableControls();
  DataSet->First();
  __try {
    while (! DataSet->Eof ) {
      ComboBox1->AddItem(DataSet->FieldByName("NOMBRE")->AsString,
        (TObject*)DataSet->FieldByName("ID")->AsInteger);
      DataSet->Next();
    }
  } __finally {
    DataSet->First();
    DataSet->EnableControls();
  }
}

void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
  int ix = ComboBox1->ItemIndex;
  String NOMBRE = ComboBox1->Items->Strings[ix];  // NOMBRE
  String ID = (int)ComboBox1->Items->Objects[ix]; // ID

  ShowMessage(NOMBRE+" "+ID); // ej: Mostrar
}

Saludos :)

ginkaku 18-10-2013 15:46:15

v:-)vv:-)v

Grande ecfisa, no tengo acceso a una dataset directamente en esta clase, pero la logica es la misma. Lo he adecuado perfectamente a mis recursos, muchas gracias funciona de maravilla.

Angel.Matilla 20-12-2013 10:36:55

Retomo este tema porque no sé que estoy haciendo mal.
Cita:

Empezado por ecfisa (Mensaje 468557)

Código:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  DataSet->DisableControls();
  DataSet->First();
  __try {
    while (! DataSet->Eof ) {
      ComboBox1->AddItem(DataSet->FieldByName("NOMBRE")->AsString,
        (TObject*)DataSet->FieldByName("ID")->AsInteger);
      DataSet->Next();
    }
  } __finally {
    DataSet->First();
    DataSet->EnableControls();
  }
}

void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
  int ix = ComboBox1->ItemIndex;
  String NOMBRE = ComboBox1->Items->Strings[ix];  // NOMBRE
  String ID = (int)ComboBox1->Items->Objects[ix]; // ID

  ShowMessage(NOMBRE+" "+ID); // ej: Mostrar
}


Hay dos cosas que no acabo de entender.
1ª. La línea de código String ID = (int)ComboBox1->Items->Objects[ix], ¿no da error al tratar de meter un int en un string?
2ª. Yo necesito buscar el valor que viene de una tabla para mostrar el ítem correspondiente. Estoy haciendo esto:
Para cargar el ComboBox:
Código:

Query->Close();
Query->SQL->Text = "SELECT Etiqueta, Valor, Literal FROM 'Instalacion.db' WHERE Etiqueta = 'Situacion' ORDER BY Valor";
Query->Open();
for (; !Query->Eof; Query->Next())
    Situacion->AddItem(Query->FieldByName("Literal")->AsString, (TObject*)Query->FieldByName("Valor")->AsInteger);

Para "leer" el contenido:
Código:

for (nItem = 0; nItem < Combo->Items->Count; nItem ++)
    nPrueba = (int)Combo->Items->Objects[nItem];

pero al correr el programa de da un mensaje List index out of bounds (1). Interpreto que trata de ir más allá del último índice cargado en el ComboBox, pero lo cierto es que tiene seis elementos y esto pasa con nItem = 1. ¿Alguna idea?

ecfisa 20-12-2013 20:58:06

Hola Angel.Matilla.

Cita:

1ª. La línea de código String ID = (int)ComboBox1->Items->Objects[ix], ¿no da error al tratar de meter un int en un string?
¿ Te da error ? (Borland C++ Builder Strings)

Cita:

al correr el programa de da un mensaje List index out of bounds (1)
Revisa que tu consulta SQL esté arrojando al menos un resultado. De no ser así, el combo estará vacío y de allí el error "índice fuera del límite".

Saludos :)

Angel.Matilla 21-12-2013 10:36:52

Cita:

Empezado por ecfisa (Mensaje 470995)
Revisa que tu consulta SQL esté arrojando al menos un resultado. De no ser así, el combo estará vacío y de allí el error "índice fuera del límite".

El query sí devuelve un resultado; de hecho ha de devolver sólo un resultado. Es que además el problema no es ese. El combo se carga con seis elementos en el OnCretae del formulario y los valores son fijos mientras se ejecuta y cuando empiezo a recorrer el bucle, con el primer valor (nItem = 0) se ejecuta bien y como el resultado de la consulta es diferente del object pasa al segundo (nItem = 1), y es en ese momento cuando salta el error: al comparar el valor de la consulta con el object, es como si tratara de ir un índice más allá de lo que corresponde
He probado otra cosa:
Código:

for (int nItem = 0; nItem < Combo->Items->Count; nItem ++)
{
    Valor = (long)(TObject*)Combo->Items->Objects[nItem];
    if (Valor == Query->FieldByName("Situacion")->AsInteger)
    {
          Combo->ItemIndex = nItem;
          break;
    }
}

y me da el mismo error. Sin embargo, si recorro el combo con este código:
Código:

AnsiString Cadena;
long Valor;

for (int i = 0; i < Combo->Items->Count; i++)
{
    Cadena = Combo->Items->Strings[i];
    Valor = (long)(TObject*)Combo->Items->Objects[i];
    ShowMessage("Cadena:" + Cadena + "\nValor: " + IntToStr(Valor));
}

Me muestra los seis valores que tiene cargados el elemento.

ecfisa 21-12-2013 19:19:26

Hola Angel.Matilla.
Cita:

Código:

for (int nItem = 0; nItem < Combo->Items->Count; nItem ++)
{
    Valor = (long)(TObject*)Combo->Items->Objects[nItem];
    if (Valor == Query->FieldByName("Situacion")->AsInteger)
    {
          Combo->ItemIndex = nItem;
          break;
    }
}


Según entiendo de ese código deseas posicionar el combo en el elemento correspondiente al entero almacenado como object, acorde a lo seleccionado en el query. Si estoy en lo correcto, no es necesario que recorras el combo, es suficiente con usar el método IndexOfObject.

Ejemplo:
Código:

{
  ComboBox->ItemIndex = ComboBox->Items->IndexOfObject((TObject*)Query->FieldByName("ID")->AsInteger);
}

Saludos :)

Angel.Matilla 22-12-2013 11:15:02

Muchas gracias por la ayuda. Lo he probado, pero sigue dando el mismo error List index out of bounds (1).


La franja horaria es GMT +2. Ahora son las 23:20:14.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi