我正在尝试使用VirtualStringTree而不是Listview来构建我的项目,因为速度差异巨大.事情是,即使在通过演示之后,我也无法弄清楚我将如何将其用作ListView.比如,添加,删除,基本上只是使用ListView项目是如此简单,但是当我看到VT时,它变得非常复杂.
我正在寻找的是一个看起来像ListView的VT,子项目等.
以下是使用ListView的一些例程,我想与VT一起使用(这只是一个伪示例:
procedure Add;
begin
with ListView.Items.Add do
Begin
Caption := EditCaption.Text;
SubItems.Add(EditSubItem.Text):
End;
end;
Procedure ReadItem(I : Integer);
begin
ShowMessage(ListView.Items[I].Caption);
ShowMessage(ListView.Items[I].SubItems[0]);
end;
当然,还有删除功能,但由于那就像1行,我没有打扰:P
任何人都可以将上面的例子翻译成使用ListView风格的VT吗?
谢谢!
解决方法
procedure Add;
Var
Data: PLogData;
XNode: PVirtualNode;
begin
with vst do
Begin
XNode := AddChild(nil);
ValidateNode(XNode,False);
Data := GetNodeData(Xnode);
Data^.Name:= EditCaption.Text;
Data^.Msg := EditSubItem.Text;
End;
end;
Procedure ReadItem(I : Integer);
var
Data: PLogData;
begin
if not Assigned(vst.Focusednode) then Exit;
Data := vst.GetNodeData(vst.Focusednode);
ShowMessage(Data^.Name);
ShowMessage(Data^.Msg);
end;
基本上这就是你需要做的,但是VirtualStringTree有很多其他的东西需要一起工作才能完全理解它.一旦你“得到它”,VST就变得简单而有力.以下网页将为您提供帮助:http://wiki.freepascal.org/VirtualTreeview_Example_for_Lazarus
以下我将添加更多用于简单VST日志显示的代码.我将所有代码保存在datamodule中,只需使用Log程序显示信息并将FormMain.vstLog更改为您的…
unit udmVstLog;
interface
uses
SysUtils,Windows,Forms,Classes,Graphics,VirtualTrees,ActnList,Dialogs,ExtDlgs;
type
PLogData = ^TLogData;
TLogData = record
IsErr : Boolean;
Name: String;
Msg : String;
end;
type
TdmVstLog = class(TDataModule)
actlst1: TActionList;
actClear: TAction;
actSave: TAction;
actcopyLine2Mem: TAction;
sdlgLog: TSaveTextFileDialog;
procedure DataModuleCreate(Sender: TObject);
procedure actClearExecute(Sender: TObject);
procedure actSaveExecute(Sender: TObject);
procedure actcopyLine2MemExecute(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
procedure VSTPaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType);
end;
procedure Log(aIsErr: Boolean; AName,AMsg: string); overload;
procedure Log(AName,AMsg: string); overload;
procedure Log(AMsg: string); overload;
var
dmVstLog: TdmVstLog;
implementation
uses uFormMain,ClipBrd;
{$R *.dfm}
procedure Log(aIsErr: Boolean; AName,AMsg: string);
Var
Data: PLogData;
XNode: PVirtualNode;
begin
XNode:=FormMain.vstLog.AddChild(nil);
FormMain.vstLog.ValidateNode(XNode,False);
Data := FormMain.vstLog.GetNodeData(Xnode);
Data^.IsErr := aIsErr;
if aIsErr then
Data^.Name:= DateTimetoStr(Now) + ' ERROR ' + AName
else
Data^.Name:= DateTimetoStr(Now) + ' INFO ' + AName;
Data^.Msg:= AMsg;
end;
procedure Log(AName,AMsg: string);
begin
Log(False,AName,AMsg);
end;
procedure Log(AMsg: string);
begin
Log(False,'',AMsg);
end;
// VirtualStringTree Events defined here
procedure TdmVstLog.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
Data: PLogData;
begin
Data:=Sender.GetNodeData(Node);
Finalize(Data^);
end;
procedure TdmVstLog.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
var
Data: PLogData;
begin
Data := Sender.GetNodeData(Node);
case Column of
0: CellText := Data^.Name + ' - '+ Data^.Msg;
end;
end;
procedure TdmVstLog.VSTPaintText(Sender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType);
Var
Data: PLogData;
begin
Data := Sender.GetNodeData(Node);
if Data^.IsErr then
TargetCanvas.Font.Color:=clRed;
end;
//PopUpMenu Actions defined here!
procedure TdmVstLog.actClearExecute(Sender: TObject);
begin
FormMain.vstLog.Clear;
end;
procedure TdmVstLog.actcopyLine2MemExecute(Sender: TObject);
var
Data: PLogData;
begin
if not Assigned(FormMain.vstLog.Focusednode) then Exit;
Data := FormMain.vstLog.GetNodeData(FormMain.vstLog.Focusednode);
ClipBoard.AsText := Data^.Name + ' - ' + Data^.Msg;
end;
procedure TdmVstLog.actSaveExecute(Sender: TObject);
Var
XNode: PVirtualNode;
Data: PLogData;
ts: TStringList;
begin
If FormMain.vstLog.GetFirst = nil then Exit;
XNode:=nil;
if sdlgLog.Execute then begin
ts:= TStringList.create;
try
Repeat
if XNode = nil then XNode:=FormMain.vstLog.GetFirst Else XNode:=FormMain.vstLog.GetNext(XNode);
Data:=FormMain.vstLog.GetNodeData(XNode);
ts.Add(Data^.Name + ' - '+ Data^.Msg);
Until XNode = FormMain.vstLog.GetLast();
ts.SavetoFile(sdlgLog.FileName);
finally
ts.Free;
end;
end;
end;
// Datamodule Events defined here
procedure TdmVstLog.DataModuleCreate(Sender: TObject);
begin
with FormMain.vstLog do begin
NodeDataSize := SizeOf(TLogData);
OnFreeNode := VSTFreeNode;
OnGetText := VSTGetText;
OnPaintText := VSTPaintText;
end;
end;
end.
…
procedure RemoveSelectednodes(vst:TVirtualStringTree); begin if vst.SelectedCount = 0 then Exit; vst.BeginUpdate; vst.DeleteSelectednodes; vst.EndUpdate; end; procedure RemoveAllNodes(vst:TVirtualStringTree); begin vst.BeginUpdate; vst.Clear; vst.EndUpdate; end;