2013-11-22 27 views
3

我想添加一個帶的TList一個TTreeViewItem和自定義類(TRoom)的另一個對象。在德爾福2007年有一個指針類型的字段'數據',這裏已經被我不知道如何使用的TValue替換。我在網上搜索了一些說明它暫時無法處理自定義類型的內容。如何使用TControl附加任何類型的對象?

有人能想出一個辦法來實現這一目標,除了製造一個黑客類?

例如,以下形式的代碼應該正常運行: -

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. 
+0

'TValue'是一個變量類型,使用'Data.AsObject' –

+0

不起作用,編譯器錯誤「不兼容的類型......」無型鑄造和「無效的類型轉換」用。 –

+0

@JerryDodge黑客類禁用了控件上的樣式,需要手動樣式分配和調用更新。 –

回答

2

如果你想一個對象「重視」的TControl,TControl類的父類TFmxObject介紹了存儲任何對象值.TagObject屬性。

除了使用此屬性外,還可以使用.Tag屬性將類型轉換爲NativeInt和想要的類類型,例如:TreeViewItem1.Tag:= NativeInt(List);和List:= TList(TreeViewItem1.Tag);

+1

標籤是沒有用好ARC我的猜測是,爲什麼TagObject存在 –

+0

@DavidHeffernan - 不,'TagObject'存在之前FMX是FMX。還有一個'TagFloat' ...... –

+0

@ChrisRolliston TagFloat?呃,爲什麼? –

1

在「小‘G’」通用的方式,一個FMX控制應該得到或設置控制的核心價值Data財產。在TImage情況下,這將位圖顯示,對於TEdit文本等。因此,它的目的與VCL樹形視圖項目的Data屬性完全不同,該屬性將任意一段數據掛在對象之外。

由於聚苯胺正確答案,如果你想掛一個任意對象引用FMX樹視圖項,那麼你可以使用TagObject也就是說之後,儘管有關的適當OOP行爲FMX的bodging刺激(見here),如果要創建樹視圖項動態再一個更好的辦法可能是得到一個定製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; 

有些人可能會認爲第二個變體的可怕混爲一談非UI用戶界面代碼然而 - 我個人並不反對(事實上,這就是爲什麼我建議它),儘管YMMV。

+0

我已經試過了,上了同一個超乎想象的造型問題,鏈接的文章確實證明有見地對其緩解,但。我以另一種方式解決了他們,但我認爲如果只需要附加一個對象,那麼更大的可用性就不值得花費額外的工作量,否則我無法駁斥您的觀點。 –

+0

@UmairAhmed - 當從TTreeViewItem直接派生時,您會遇到樣式問題...? –

+0

是的,我做了,我通過在新的構造函數中傳遞和設置父項來解決這個問題,它在BeginUpdate/EndUpdate塊中完成創建的地方工作,否則它將手動設置爲默認的treeviewitemstyle以使其工作。我沒有找到受保護的FStyleLookup。 –

相關問題