今天上午终于完成了重中之重的drag 和drop
看了这么长时间都不甚明了的代码,今天终于实现了
有以下体会:
1。数据结构很重要,选择了好的结构,能让你的思路更清晰,代码更健壮,可维护性更强。
比不如我在实现中 使用了changeList :TStringList;保存中间量,让我少了很多的麻烦
2。不会不要紧,要紧的是学的时候一定要专注,要明确自己的目标。
本来预计用一天的时间来解决这个问题,结果上午虽然忙得不亦乐乎,倒也一点点接近目标,顺利解决,
心中很是快哉。
源代码如下:
procedure TScriptsForm.DataTreeDragOver(Sender: TBaseVirtualTree;
Source: TObject; Shift: TShiftState; State: TDragState; Pt: TPoint;
Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
var
pnode2: PAdminNode;
data: PInt;
Node2: PVirtualNode;
begin
Accept := False;
if (Source is TVirtualStringTree) then //Source 为 TBaseVirtualTree 树中的一行,注意与下面的区别
begin
if DataTree.FocusedNode.Index=0 then
Accept:=False
else
accept := true;
Exit;
end;
if Source is TBaseVirtualTree then //Source 为 TBaseVirtualTree ,即为整个树
begin
Node2 := (Source as TBaseVirtualTree).GetFirstSelected;
data := (Source as TBaseVirtualTree).GetNodeData(Node2);
pnode2 := Pointer(data^);
if (pnode2.nodetype = 2) and (pnode2.id <> Self.FID) then
Accept := True;
Exit;
end;
end;
procedure TScriptsForm.DataTreeDragDrop(Sender: TBaseVirtualTree;
Source: TObject; DataObject: IDataObject; Formats: TFormatArray;
Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
var
pnode2: PAdminNode;
data: PInt;
Node2: PVirtualNode;
sql: string;
changeList :TStringList;
FocusNode:PVirtualNode;
TargetNode:PVirtualNode;
i:Integer;
begin
Effect := DROPEFFECT_NONE;
if Source is TVirtualStringTree then
begin
if DataTree.DropTargetNode =nil then Exit;
if DataTree.DropTargetNode.Index=0 then Exit;
changeList:=TStringList.Create;
FocusNode:=DataTree.FocusedNode;
TargetNode:=DataTree.DropTargetNode;
if FocusNode.Index > TargetNode.Index then //如果下移
begin
changeList.Add(stringlist.Strings[FocusNode.index]);
for i:=TargetNode.Index to FocusNode.Index-1 do
changeList.Add(stringlist.Strings[i]);
for i:=TargetNode.Index to FocusNode.Index do
stringlist.Strings[i]:= changeList.Strings[i-TargetNode.Index]; //更新stringlist中的相应项,下同
end;
if FocusNode.Index < TargetNode.Index then //如果上移
begin
for i:=FocusNode.Index+1 to targetnode.Index do
changeList.add(stringlist.Strings[i]);
changeList.Add(stringlist.Strings[FocusNode.index]);
for i:=FocusNode.Index to TargetNode.Index do
stringlist.Strings[i]:= changeList.Strings[i-FocusNode.Index];
end;
//下面两句更新树的视图(重新载入发现更改未保存),要真正更改顺序,还需要点击Save
self.DataTree.RootNodeCount:=stringlist.Count;
DataTree.Refresh;
Exit;
end;
if Source is TBaseVirtualTree then
begin
if application.MessageBox('Are you sure to replace current script?', 'Message', MB_OKCANCEL) = IDCancel then
exit;
Node2 := (Source as TBaseVirtualTree).GetFirstSelected;
data := (Source as TBaseVirtualTree).GetNodeData(Node2);
pnode2 := Pointer(data^);
sql := 'Select texts from systemobjects where itemid=''' + pnode2.id + '''';
currentdatabase.ExeuteSQlQurey(pnode2, sql, @GetScriptFromDB);
Self.SetScript(pnode2.texts);
Exit;
end;
飞飞于北京
2005-8-19