実際の項目とともに id 値を保持できるように、列の 1 つが非表示になっている 2 つの列を持つTComboBoxを作成する方法は? そして、その id 値をプログラムで取得する方法は?
2 に答える
ここに 2 つの列は必要ありません。
TComboBox.Items
(Delphi の他の多くのものと同様TStringList
に、TMemo.Lines
、 、 などTListBox.Items
) は と の両方のプロパティを持つ から派生してTStrings
いるという事実を利用できます。ポインタであるのサイズのすべてを格納します。Strings
Objects
Objects
TObject
これは、整数値を追加するときにTObjectに型キャストし、取得するときにIntegerに型キャストするだけで、整数値を格納できることを意味します。
このようなものが動作するはずです:
procedure TForm1.FormCreate(Snder: TObject);
var
i: Integer;
sItem: String;
begin
for i := 0 to 9 do
begin
sItem := Format('Item %d', [i]);
ComboBox1.Items.AddObject(sItem, TObject(i));
end;
end;
値を取得するには:
procedure TForm1.ComboBox1Click(Sender: TObject);
var
Idx: Integer;
Value: Integer;
begin
Idx := ComboBox1.ItemIndex;
if Idx <> -1 then
begin
Value := Integer(ComboBox1.Items.Objects[Idx]);
// Do something with value you retrieved
end;
end;
Objectsプロパティは実際にはオブジェクトを格納するためのものであるため、これにより多くの柔軟性が得られることに注意してください。これは、関連付けられたオブジェクト インスタンスに顧客の連絡先情報を格納し、リスト ボックスの項目が選択されたときにそれをラベルに表示する例です (意図的に非常に簡単にします)。
unit Unit1;
interface
uses
Windows, Messages, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TCustomer=class
private
FContact: string;
FPhone: string;
public
constructor CreateCustomer(const AContact, APhone: string);
property Contact: string read FContact write FContact;
property Phone: string read FPhone write FPhone;
end;
TForm1 = class(TForm)
ListBox1: TListBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
lblContact: TLabel;
lblPhone: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ListBox1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TCustomer }
constructor TCustomer.CreateCustomer(const AContact, APhone: string);
begin
inherited Create;
FContact := AContact;
FPhone := APhone;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i: Integer;
begin
for i := 0 to ListBox1.Items.Count - 1 do
ListBox1.Items.Objects[i].Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
lblContact.Caption := '';
lblPhone.Caption := '';
// Create some customers. Of course in the real world you'd load this
// from some persistent source instead of hard-coding them here.
ListBox1.Items.AddObject('N Company', TCustomer.CreateCustomer('Nancy', '555-3333'));
ListBox1.Items.AddObject('B Company', TCustomer.CreateCustomer('Brad', '555-1212'));
ListBox1.Items.AddObject('A Company', TCustomer.CreateCustomer('Angie', '555-2345'));
end;
procedure TForm1.ListBox1Click(Sender: TObject);
var
Cust: TCustomer;
begin
if ListBox1.ItemIndex <> -1 then
begin
Cust := TCustomer(ListBox1.Items.Objects[ListBox1.ItemIndex]);
lblContact.Caption := Cust.Contact;
lblPhone.Caption := Cust.Phone;
end;
end;
end.
ComboBox コントロールは列をサポートしていないため、目的を達成するために非表示の列は必要ありません。
TComboBox.Items
プロパティは子孫TStrings
です。文字列値と関連するユーザー定義データ値の両方を同時に保持できますが、ユーザーは UI に文字列値しか表示しません。メソッドを使用してItems.AddObject()
文字列 + ID 値をリストに追加し、必要に応じてItems.Objects[]
プロパティを使用して ID 値を取得します。
または、ComboBox と同じ数の要素を持つ別の配列に ID 値を格納し、ComboBox アイテム インデックスを使用して配列値にアクセスすることもできます。これは、-1 の値を格納する必要がある場合に特に重要です。ロブが言ったように、getter メソッドの実装方法により、特定の値Objects[]
を a のプロパティから取得できないためです。TComboBox