Como associar dados a um item (Combobox ou Listbox)
Dois dos componentes mais usados em Delphi são as Combobox e as Listbox. São componentes muito semelhantes, na medida em que ambos contém uma lista de items que o utilizador pode escolher e selecionar, sendo que a diferença entre ambos é que na Listbox, a lista aparece sempre visível, enquanto na Combobox, a lista só é visível no momento da seleção, deixando apenas o item selecionado visível quando em "stand-by":
O que acontece por vezes é que, além da string que representa cada itens das listas, queremos guardar alguma outra informação, associada a cada item. Por exemplo, queremos guardar numa lista nomes de ficheiros, mas queremos guardar também o caminho onde esse ficheiro está guardado (sem que ele seja visível). Ou se quisermos guardar na lista nomes de pessoas, mas associar a sua idade para usar mais tarde. Ou ir mais longe, e junto com o nome da pessoa, guardar todo um conjunto de dados, como data de nascimento, sexo, nacionalidade, etc.
Claro, seria possível guardar qualquer outra informação numa variável/componente à parte, e manter uma associação através do índice da lista, mas a probabilidade de erro disto é grande, pois é necessário que de cada vez que se insira ou elimine um registo na lista, também se faça isso no "armazém" de dados, e com o cuidado adicional de manter os índices iguais entre as duas!
Felizmente, nada disto é necessário...
Ambos os componentes, bem como todos que usem o tipo TSrings para guardar dados, possuem a capacidade de guardar um objeto (TObject) junto com a string que constitui o texto.
A vantagem do TObject é que pode guardar qualquer tipo de dados, e como tal, qualquer que seja a informação que precisamos guardar junto com o item, pode ser convertida em TObject e guardada na lista. Basta que para isso se use uma funcionalidade chamada TypeCasting (o que permite converter entre tipos de dados em runtime).
Ex.1: Guardar o nome de um ficheiro (visível) e o caminho (invisível):
var
FileName,FilePath:String;
.
.
.
ComboBox1.AddItem (FileName, TObject (FilePath)); // O primeiro parâmetro é o item visível, o segundo é o objeto associado, neste caso, typecasted de string para TObject
.
.
.
// para usar os dados bastaria usar o seguinte:
ShowMessage ('O caminho completo do ficheiro é:' + #13#10 + String (ComboBox1.Items.Objects[ComboBox1.ItemIndex]) + ComboBox1.Items [ComboBox1.ItemIndex]);
// Agora, fez-se o typecast de TObject para String
Ex.2: Guardar um nome (visível) e a idade (invisível):
var
Nome:String;
Idade:Integer;
.
.
.
combobox2.AddItem (Nome,TObject (Idade)); // Neste caso, a variável Idade foi typecasted de integer para TObject
.
.
.
// para usar os dados bastaria usar o seguinte:
ShowMessage ('O(a) ' + ComboBox2.Items [ComboBox2.ItemIndex] + ' tem ' + IntToStr (Integer (ComboBox2.Items.Objects [ComboBox2.ItemIndex])) + ' anos.');
// Agora, fez-se o typecast de TObject para Integer
Ex.3: Guardar um nome (visível) e um conjunto de dados associados (invisível):
type
TDados=record
Nome:String;
DataNasc:TDate;
Sexo:Char;
Nacionalidade:String;
end;
var
Pessoa:TDados;
.
.
.
ComboBox3.AddItem (Pessoa.Nome, TObject (Pessoa)); // Neste caso, a variável Pessoa foi typecasted de TDados para TObject
.
.
.
// para usar os dados bastaria usar o seguinte:
Pessoa:=TDados (ComboBox3.Items. Objects [ComboBox3.ItemIndex]); // Agora, fez-se o typecast de TObject para TDados
ShowMessage (Pessoa.Nome+#13#13#10+'Data de Nascimento: ' + Pessoa.DataNasc + #13#10 + 'Sexo: ' + Pessoa.Sexo + #13#10 + 'Nacionalidade: ' + Pessoa.Nacionalidade);
Assim, usando o mesmo índice (neste caso, foi usado a propriedade ItemIndex das Combobox para devolver o item selecionado), conseguimos aceder tanto ao item propriamente dito (o que é visível na lista para o utilizador) como ao objeto associado, através do uso de TypeCasting para converter de e para o tipo TObject.