Как прикрепить объект любого типа с помощью TControl?

Я хочу добавить TList с TTreeViewItem и объект пользовательского класса (TRoom) с другим. В delphi 2007 появилось поле "Данные" типа Pointer, которое было заменено на TValue, которое я не знаю, как использовать. Я искал в Интернете некоторые утверждения, что он не может обрабатывать пользовательские типы в настоящее время.

Может кто-нибудь придумать способ добиться этого, кроме как взломать урок?

Например, следующий код формы должен работать правильно:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
  FMX.TreeView, FMX.Layouts, FMX.Edit;

type
  TRoom = class

    ID : WORD;
    Name : String;

  end;

  TForm1 = class(TForm)
    TreeView1: TTreeView;
    TreeViewItem1: TTreeViewItem;
    Button1: TButton;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
  List : TList;
begin

  // Get The List From TreeViewItem1
  // pani's Solution  - List := TList ( TreeViewItem1.TagObject );

  Edit1.Text := TRoom ( List.First ).Name;

end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Room : TRoom;
  List : TList;

begin

  List := TList.Create;
  Room := TRoom.Create;
  Room.ID := 5;
  Room.Name := IntToStr ( 5 );
  List.Add ( Room );

  // Add The List To TreeViewItem1    
  // pani's Solution  - TreeViewItem1.TagObject := List;

end;

end.

2 ответа

Решение

Если вы хотите "прикрепить" объект к TControl, родительский класс TControl TFmxObject представляет свойство.TagObject, в котором хранится любое значение объекта.

Помимо использования этого свойства вы также можете использовать свойство.Tag с приведением типов в NativeInt и типом нужного вам класса, например: TreeViewItem1.Tag:= NativeInt(List); и список:= TList(TreeViewItem1.Tag);

В "маленьком" g "родовом стиле, Data свойство элемента управления FMX должно получить или установить значение ядра элемента управления. В TImage если это будет отображаемое растровое изображение, для TEdit текст и тд. Таким образом, его назначение полностью отличается от Data свойство элемента представления дерева VCL, которое должно повесить произвольную часть данных от объекта.

Как правильно ответит pani, если вы хотите повесить произвольную ссылку на объект на элемент дерева FMX, вы можете использовать TagObject, Тем не менее, несмотря на раздражения, связанные с использованием FMX правильного поведения ООП (см. Здесь), если вы создаете элементы в виде дерева динамически, то лучшим способом может быть получение пользовательского TTreeViewItem потомок:

uses System.Generics.Collections;

type
  TRoomTreeViewItem = class(TTreeViewItem)
    RoomList: TList<TRoom>; //better use a generic than non-generic list as mentioned above
  end;

Или, если время жизни списка комнат совпадает со временем жизни элемента дерева, с которым он связан, вы можете фактически инкапсулировать список в элементе:

type
  TRoomTreeViewItem = class(TTreeViewItem)
  strict private
    FRoomList: TObjectList<TRoom>;
    function GetRoom(Index: Integer): TRoom;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function GetEnumerator: TEnumerator<TRoom>;
    function AddRoom: TRoom;
    property Rooms[Index: Integer] read GetRoom;
  end;

constructor TRoomTreeViewItem.Create(AOwner: TComponent);
begin
  inherited;
  FRoomList := TObjectList<TRoom>.Create;
end;

destructor TRoomTreeViewItem.Destroy;
begin
  FRoomList.Free;
  inherited;
end;

function TRoomTreeViewItem.GetEnumerator: TEnumerator<TRoom>;
begin
  Result := FRoomList.GetEnumerator;
end;

function TRoomTreeViewItem.GetRoom(Index: Integer): TRoom;
begin
  Result := FRoomList[Index];
end;

function TRoomTreeViewItem.AddRoom: TRoom;
begin
  Result := TRoom.Create;
  FRoomList.Add(Result);
end;

Однако некоторые люди могут считать второй вариант ужасным соединением не-пользовательского интерфейса с кодом пользовательского интерфейса - лично я не против (действительно, именно поэтому я и предложил), хотя YMMV.

Другие вопросы по тегам