Delphi TTreeView 组件 (可以 "Win32" 组件面板中找到) 用于显示一个分级项目的窗口. 每一项 (树节点) 包含一个标签和一个可选的位图 (两个更准确). XML 使开发者能更好的运用结构数据. XML文档的结构与TreeView的结构非常相似. Delphi中, TXMLDocument (可以 "Internet" 组件面板找到) 可以被用于表示一个XML文档. 本文将教您怎样保存树目录到XML文件及怎样从XML文档重建一个树型目录. 如果您需要一个强大、易传输的格式来保存应用程序的配置, 使用TreeView与XML是一个非常好的选择, 接下来请看...... 保存TTreeView项目到XML首先, 我们新建一个简单的应用程序, 并放置几个组件: 一个TTreeView组件, 两个ImageList组件及一个TXMLDocument组件. 其中的一个图像列表组件用于关联TreeView的Images属性, 另一个用于关联StateImages属性 (请参考: 如何给TreeView 添加复选框和单选按钮 ). 这是程序运行时的一个截屏. Tree2XML 过程用于保存树型目录到一个XML文档. 它只有一个参数, 用于给出要保存到XML的TTreeView组件. XML文档使用与应用程序相同的文件名 (当然, 要用'.XML'作为扩展名) 该过程遍历整个TreeView, 每次都调用子过程 ProcessTreeItem. 子过程ProcessTreeItem在同一级节点中递归调用. 该递归算法确保整个TreeView的节点都被处理. 对于每个目录项, 一个XML节点 (IXMLNode) 被建立, 并带有表示Text的属性值和ImageIndex、StateIndex属性. 节点实际上保存了所有与树节点有关的值. 一旦全部树目录项被处理完毕, XML文件也被保存. 注意: 过程ProcessTreeItem被动态创建和操作 TXMLDocument (XMLDoc)组件.
procedure Tree2XML(tree: TTreeView);
var
tn : TTreeNode;
XMLDoc : TXMLDocument;
iNode : IXMLNode;
procedure ProcessTreeItem(
tn : TTreeNode;
iNode : IXMLNode);
var
cNode : IXMLNode;
begin
if (tn = nil) then Exit;
cNode := iNode.AddChild('item');
cNode.Attributes['text'] := tn.Text;
cNode.Attributes['imageIndex'] := tn.ImageIndex;
cNode.Attributes['stateIndex'] := tn.StateIndex;
//子节点
tn := tn.getFirstChild;
while tn <> nil do
begin
ProcessTreeItem(tn, cNode);
tn := tn.getNextSibling;
end;
end; (*ProcessTreeItem*)
begin
XMLDoc := TXMLDocument.Create(nil);
XMLDoc.Active := True;
iNode := XMLDoc.AddChild('tree2xml');
iNode.Attributes['app'] := ParamStr(0);
tn := tree.TopItem;
while tn <> nil do
begin
ProcessTreeItem (tn, iNode);
tn := tn.getNextSibling;
end;
XMLDoc.SaveToFile(ChangeFileExt(ParamStr(0),'.XML'));
XMLDoc := nil;
end; (* Tree2XML *)
| 实际应用中, 您可以在应用程序关闭时导出TTreeView到XML, 使用Form的OnCloseQuery 事件来询问用户是否保存:
// tree是TTreeView 组件的名字
procedure TForm1.FormCloseQuery(
Sender: TObject;
var CanClose: Boolean);
begin
case MessageDlg('Save tree items to XML?',
mtConfirmation,
[mbYes, mbNo, mbCancel], 0) of
mrYes:
Tree2XML(tree);
mrNo:
CanClose := True;
mrCancel:
CanClose := False;
end;
end;
| 下面是导出XML文档的结果.
从XML装载TTreeView项目一旦我们有了表示TreeView的XML文件, 我们就能使用它来填充TreeView了. 当应用程序启动时, XML2Tree 过程被调用来构造树目录. tree 参数表示我们要填充的TTreeView组件; XMLDoc 参数指向一个TXMLDocument组件.
procedure XML2Tree(
tree : TTreeView;
XMLDoc : TXMLDocument);
var
iNode : IXMLNode;
procedure ProcessNode(
Node : IXMLNode;
tn : TTreeNode);
var
cNode : IXMLNode;
begin
if Node = nil then Exit;
with Node do
begin
tn := tree.Items.AddChild(tn, Attributes['text']);
tn.ImageIndex := Integer(Attributes['imageIndex']);
tn.StateIndex := Integer(Attributes['stateIndex']);
end;
cNode := Node.ChildNodes.First;
while cNode <> nil do
begin
ProcessNode(cNode, tn);
cNode := cNode.NextSibling;
end;
end; (*ProcessNode*)
begin
tree.Items.Clear;
XMLDoc.FileName := ChangeFileExt(ParamStr(0),'.XML');
XMLDoc.Active := True;
iNode := XMLDoc.DocumentElement.ChildNodes.First;
while iNode <> nil do
begin
ProcessNode(iNode,nil);
iNode := iNode.NextSibling;
end;
XMLDoc.Active := False;
end;
| XML2Tree 过程基本上与Tree2XML 操作原理相似. 代码遍历所有的XML节点, 创建 TTreeNode 对象并添加到 TreeView 组件. 就是这样老实说, 在现在的项目中, 我已经很少用 Registry 或 INI files 来保存配置数据了. XML似乎更友好. 你可以下载本文 完整的源代码. 如果您需要帮助, 请在 Delphi Programming Forum 提出你的问题. |