我正在使用Zarko Gajic's Store More (Custom) Data Into The Tree Node Of A Tree View爲每個節點項目添加附加字符串,但是我發現如果我的應用程序長時間處於空閒狀態,那麼存儲在自定義樹節點中的值將消失。如何防止TTreeView的自定義樹節點數據丟失?
這是我的自定義樹節點看上去就像我離開的時候昨日
這是它看起來像今天早上(注意fMyProperty值現在是空的)
我已確認我的電腦從不休眠或睡眠,但系統在鎖定1分鐘後確實會關閉顯示器以節能。但是,計算機需要閒置一段時間才能發生此問題。它在夜間空閒時最爲明顯,但如果只閒置30分鐘,則不太可能發生。
我能想到的唯一可導致這種情況的原因是操作系統將應用程序內存交換到磁盤,並且當您重新激活計算機時,它將被交換回內存。正如你所看到的,FItemId正在改變,所以它似乎是「重建」Treeview,從而失去了與自定義Tree節點的關聯。
我已經用非常簡單的應用程序轉載了這個問題,代碼如下。
我知道我可以使用另一種方法來存儲額外的數據,通過使用Treenode中的數據字段,但它能夠做到這一點很好,因爲我不必擔心釋放額外的內存塊當節點被刪除時。
我該怎麼做才能防止這種數據丟失的發生?
unit Test04Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls;
type
TMyTreeNode = class(TTreeNode)
private
fMyProperty : string;
public
property MyProperty : string read fMyProperty write fMyProperty;
end;
TForm1 = class(TForm)
TreeView1: TTreeView;
StatusBar1: TStatusBar;
procedure FormCreate(Sender: TObject);
procedure TreeView1CreateNodeClass(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass);
procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
private
fTreeView1_Selected: TMyTreeNode;
property TreeView1_Selected : TMyTreeNode read fTreeView1_Selected;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
tn : TTreeNode;
cnt : integer;
begin
//fill some items
TreeView1.Items.Clear;
for cnt := 0 to 9 do
begin
tn := TreeView1.Items.AddChild(nil, IntToStr(cnt));
//add default MyProperty values
TMyTreeNode(tn).MyProperty := 'this is node ' + IntToStr(cnt);
end;
end;
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
fTreeView1_Selected := TMyTreeNode(Node);
StatusBar1.Panels[0].Text := TreeView1_Selected.MyProperty;
end;
procedure TForm1.TreeView1CreateNodeClass(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass);
begin
NodeClass := TMyTreeNode;
end;
end.
在Windows 2012 R2上使用Delphi XE6調試Win32版本,但Win64版本也會出現此問題。
謝謝你的解釋:)我將使用數據功能。 – KeyszerS
可以使用自定義節點類型作爲Data的類型安全包裝。另一方面,這也可以通過TTreeNode上的本地類助手完成。 –
這兩個選項都非常好@Uwe,謝謝 –