Перейти к содержанию
Fire Monkey от А до Я
  • 0

[TComboBox] Как сохранять ID в Combobox?


VladimirS

Вопрос

Рекомендуемые сообщения

  • 0

Странно, проверял на XE7 Update 1 работает нормально

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(Integer(ComboBox1.Selected.Data).ToString);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ComboBox1.Items.AddObject('User1', TObject(1));
  ComboBox1.Items.AddObject('Uset2', TObject(2));
end;

Ссылка на комментарий
  • 0
  • Администраторы

Описанная проблема зависит от платформы, а именно от ARC. Подобная тема была тут: У меня возникает ошибка при попытке добавить пустой TObject в TStringList

 

Какие есть варианты решения:

  1. Использовать объектную оболочку вашего ID. Смотрите предложение от haword
  2. Использовать свойство Tag у итема TListBoxItem
Ссылка на комментарий
  • 0
  • Администраторы

Честно говоря, не смотря на то, что у TComboBox есть свойство Items. Я советую использовать ручное создание итемов. Так как TComboBox и TComboEdit имеют принципиально разные подходы к своим итемам. 
 
Если TComboBox поддерживает стилизацию итемов, то TComboEdit нет. Поэтому в TComboEdit работа с итемами идет через строковые Items. А в TComboBox исторически нужно было создавать TListBoxItem ручками. При ручном создании итемов мы можем:

  • Создать специальный свой класс итема (наследник TListBoxItem), который будет поддерживать поле TField. И хранить все что нам захочется в любом виде и формате. Так же это будет хороший артефакт для дальнейших ваших разработок с участием БД.
  • Избавиться от проблем, связанных с ARC и хранением своих данных.

Самый простой пример:

type
  TListBoxItemField = class(TListBoxItem)
  private
    FID: Integer;
  public
    property ID: Integer read FID write FID:
  end;


// Создание итема
var
  Item: TListBoxItemField;
begin
  Item := TListBoxItemField.Create(nil);
  Item.Text := 'My Item';
  Item.ID := 1;
  Item.Parent := ComboBox1;
end;

//Доступ к итему
ComboBox1.ListItems[Index] as TListBoxItemField

А можно в таком итеме сразу хранить поле типа TValue. В этом случае в такой итем можно будет сохранять значение любого типа.

Ссылка на комментарий
  • 0

Пока что склоняюсь к варианту. предложенному GunSmoker:

type
{$IFDEF AUTOREFCOUNT}
  TContainerObject = class
  strict private
    FValue: Variant;
  protected
    constructor Create(const AValue: Variant);
  public
    property Value: Variant read FValue;
  end;

constructor TContainerObject.Create(const AValue: Variant);
begin
  inherited Create;
  FValue := AValue;
end;

function FakeObject(const AValue: Variant): TObject;
begin
  Result := TContainerObject.Create(AValue);
end;

function RealObject(const AObject: TObject): Variant;
begin
  Result := (AObject as TContainerObject).Value;
end;
{$ELSE}
  FakeObject = TObject;
  RealObject = Cardinal;
{$ENDIF}


List.AddObject('Some value', FakeObject(ID));
ID := RealObject(List.Objects[0]);
Ссылка на комментарий
  • 0
  • Администраторы

Вариант хорош, но потом нужно будет при очистке списка в каждом месте опять дефайны лепить. Чтобы утечек не было. По мне так проще использовать универсальный подход.

Ссылка на комментарий
Гость
Эта тема закрыта для публикации ответов.
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...