电脑爱好者,提供IT资讯信息及各类编程知识文章介绍,欢迎大家来本站学习电脑知识。 最近更新 | 联系我们 RSS订阅本站最新文章
电脑爱好者
站内搜索: 
当前位置:首页>> delphi技术>>创建XML Datasets及动态控件:

创建XML Datasets及动态控件

来源:www.cncfan.com | 2006-1-20 | (有4255人读过)

本文介绍了如何创建XML dataset,然后通过XML文件里的元素对XML“表”动态地创建相应控件。
本文介绍了如何创建XML dataset,然后通过XML文件里的元素对XML“表”动态地创建相应控件。文末所附的工程(Project)文件,使用户可以创建简单的(非关系型)数据库,这个数据库用XML文件存储。随后加载这个XML文件,经解析之后,可以在用户自行定义的“数据库”输入界面上动态生成控件。

大家都习惯使用Delphi来编程,实在太容易了。一桩困难的任务可以变得简单得多,伤透脑筋的结构设计可以轻易完成。感谢Delphi提供的这种灵活实用的工具,和优雅的界面风格。

Delphi 6问世,提供了新的组件,使开发者能够创建和管理XML文件。例如,在Interner组里提供了XMLDocument组件,在Data Access组里提供了XMLTransform, XMLTransformProvider, and XMLTransformClient组件集。

另外,在主菜单的File | New | Other | New下,你能找到XML数据绑定向导(XML Data Binding Wizard)。如果还不够,你可以使用XML映象器(Tools | XML Mapper or Programs | Borland Delphi 6 | XML Mapper)。尽管Delphi已经提供了如此之多的捷径来产生和使用XML文件,Borland公司还是向我们提供了“免动脑筋”的解决方案 - 使用“即试即用”的TClientDataSet。

从TClientDataSet到XML
用TClientDataSet创建和加载XML文件是很容易的,调用SaveToFile和LoadToFile函数即可,只要对函数的第二个参数设置相应的XML类型。实际上,有三个参数类型,一个是遗留的dfBinary二进制类型,另外是dfXMLUTF8和UTF8-based XML类型。

例如,可以这样存储文件(代码中的cds是TClientDataSet,FCurrentDataBaseName是文件名):
cds.SaveToFile(Format('%s.xml', [FCurrentDataBaseName]), dfXMLUTF8);
这样你就得到了XML文件。

动态创建相应的控件
当然,在调用SaveToFile之前,还得创建数据库。这也不难,如下例。假设有两个TListBox控件,一个存放域名(lstbxFields),另一个存放相应的数据类型(lstbxDataTypes),动态创建控件的过程如下:

{----------------------------------------------------}
procedure TfEZDBBrowserAddEditDelete.Cre8Controls;
const
 { DYNAMIC_CONTROLS_TOP:第一个控件与顶部的距离}
 DYNAMIC_CONTROLS_TOP = 24;
 DYNAMIC_CONTROLS_LEFT = 12;
 { 为简短起见,省略其它常量}
var
 i: Integer;
 iCurrentRow, iCurrentTop, iControlsOnThisRow, iCurrentWidthOfControls: Integer;
 MemoOnThisRow: Boolean;

procedure Cre8StringLabeledEdit(ACaption: String);
begin
 with TLabeledEdit.Create(Self) do
 begin
  Parent := scrlbx;
  Name := Format('lbledt%s', [ACaption]);
  { HelpContext用于映射控件和表格索引(grid index 3 = (control with HelpContext 3), 等等)}
  HelpContext := HELP_CONTEXT_OFFSET+i;
  Hint := ACaption;
  EditLabel.Caption := ACaption;
  EditLabel.Font.Style := EditLabel.Font.Style+[fsBold];
  Text := '';
  { 扩展宽度,使可输入长串}
  Width := LABELED_EDIT_STRING_WIDTH;
  grdcds.Columns[i].Width := GRID_COLUMN_ALPHA_WIDTH;
  { 如果当前行宽不合适,去下一行}
  if (iCurrentWidthOfControls + LABELED_EDIT_STRING_WIDTH +
   (SPACE_BETWEEN_DYNAMICALLY_CREATED_CONTROLS * iControlsOnThisRow)) >
   MAX_WIDTH_OF_CONTROLS then
  begin
   inc(iCurrentRow);
   iControlsOnThisRow := 1;
   if MemoOnThisRow then
    Top := (SPACE_BETWEEN_DYNAMICALLY_CRE8ED_ROWS * iCurrentRow)+MEMO_HEIGHT
   else
    Top := iCurrentTop+SPACE_BETWEEN_DYNAMICALLY_CRE8ED_ROWS;
   iCurrentTop := Top;
   MemoOnThisRow := False;
   Left := DYNAMIC_CONTROLS_LEFT;
   iCurrentWidthOfControls := LABELED_EDIT_STRING_WIDTH;
  end
  else
  begin
   Top := iCurrentTop;
   if iCurrentWidthOfControls = 0 then
   begin
    Left := DYNAMIC_CONTROLS_LEFT;
    if iCurrentRow=0 then
     FFirstDynamicControl := Name;
   end
   else
    Left := iCurrentWidthOfControls + (SPACE_BETWEEN_DYNAMICALLY_CREATED_CONTROLS *
       iControlsOnThisRow) + DYNAMIC_CONTROLS_LEFT;
   inc(iControlsOnThisRow);
   iCurrentWidthOfControls := iCurrentWidthOfControls + LABELED_EDIT_STRING_WIDTH;
  end;
  OnEnter := DynamicControlEnter;
  OnExit := DynamicControlExit;
  Tag := LABELED_EDIT_STRING_TAG;
 end;
end;

{ 创建Memos有一个特别问题:Memo很长时,要随时保留回车键("crlf")位置,用于调整屏幕顶端位置。}

procedure Cre8Memo(ACaption: String);
var mmoLeft, mmoTop: Integer;
begin
 with TMemo.Create(Self) do
 begin
  Parent := scrlbx;
  Name := Format('mmo%s', [ACaption]);
  HelpContext := HELP_CONTEXT_OFFSET+i;
  Hint := ACaption;
  Text := '';
  Scrollbars := ssVertical;
  { 如果当前行宽不合适,去下一行}
  if (iCurrentWidthOfControls + MEMO_WIDTH + (SPACE_BETWEEN_DYNAMICALLY_CREATED_CONTROLS *
   iControlsOnThisRow)) > MAX_WIDTH_OF_CONTROLS then
  begin
   inc(iCurrentRow);
   iControlsOnThisRow := 1;
   if MemoOnThisRow then
    Top := iCurrentTop + SPACE_BETWEEN_DYNAMICALLY_CRE8ED_ROWS + MEMO_HEIGHT
   else
    Top := iCurrentTop + SPACE_BETWEEN_DYNAMICALLY_CRE8ED_ROWS;
   iCurrentTop := Top;
   Left := DYNAMIC_CONTROLS_LEFT;
   iCurrentWidthOfControls := MEMO_WIDTH;
  end
  else
  begin
   Top := iCurrentTop;
   if iCurrentWidthOfControls = 0 then
   begin
    Left := DYNAMIC_CONTROLS_LEFT;
    if iCurrentRow=0 then
     FFirstDynamicControl := Name;
   end
   else
    Left := iCurrentWidthOfControls + (SPACE_BETWEEN_DYNAMICALLY_CREATED_CONTROLS *
       iControlsOnThisRow) + DYNAMIC_CONTROLS_LEFT;
   inc(iControlsOnThisRow);
   iCurrentWidthOfControls := iCurrentWidthOfControls + MEMO_WIDTH;
  end;
  { 现在可以在行例设置memo了}
  MemoOnThisRow := True;
  mmoLeft := Left;
  mmoTop := Top;
  OnEnter := DynamicControlEnter;
  OnExit := DynamicControlExit;
  Tag := MEMO_MEMO_TAG;
 end;
 { 在上面设置标签}
 with TLabel.Create(Self) do
 begin
  Parent := scrlbx;
  { 也许可以不用Name... }
  Name := Format('lbl%s', [ACaption]);
  Caption := ACaption;
  Font.Style := Font.Style+[fsBold];
  Left := mmoLeft;
  Top := mmoTop-LBL_VERTICAL_DELTA;
 end;
end;

procedure Cre8MoneyLabeledEdit(ACaption: String);
{为简短起见,这里省略代码,可到附件下载}

procedure Cre8IntegerLabeledEdit(ACaption: String);
{为简短起见,这里省略代码,可到附件下载}

procedure Cre8FloatLabeledEdit(ACaption: String);
{为简短起见,这里省略代码,可到附件下载}

procedure Cre8ComboBox(ACaption: String);
{为简短起见,这里省略代码,可到附件下载}
begin { 初始化变量}
iCurrentRow := 0;
iCurrentWidthOfControls := 0;
iControlsOnThisRow := 0;
iCurrentTop := DYNAMIC_CONTROLS_TOP;
MemoOnThisRow := False;
dm.cds.Active := True;
{ Do not want to do this in the DM's Create, as the CDS must be active first }
dm.cds.LogChanges := False;
for i := 0 to Pred(dm.CDS.FieldList.Count) do
begin
 with dm.CDS.Fields do
  begin
   if (Fields[i] is TStringField) then
    Cre8StringLabeledEdit(Fields[i].FieldName)
   else if (Fields[i] is TMemoField) then
    Cre8Memo(Fields[i].FieldName)
   else if (Fields[i] is TCurrencyField) then
    Cre8MoneyLabeledEdit(Fields[i].FieldName)
   else if (Fields[i] is TIntegerField) then
    Cre8IntegerLabeledEdit(Fields[i].FieldName)
   else if (Fields[i] is TFloatField) then
    Cre8FloatLabeledEdit(Fields[i].FieldName)
   else if (Fields[i] is TDateField) then
    Cre8DateTimePicker(Fields[i].FieldName)
   else if (Fields[i] is TBooleanField) then
    Cre8ComboBox(Fields[i].FieldName);
  end;
 end;
 Popul8DynamicControls;
end;
上一篇Delphi 6 XML
下一篇XML格式的聊天程序
delphi技术热门文章排行
网站赞助商
购买此位置

 

关于我们 | 网站地图 | 文档一览 | 友情链接| 联系我们

Copyright © 2003-2024 电脑爱好者 版权所有 备案号:鲁ICP备09059398号