根据数据库查询结果动态创建控件(仿看板模式显示)

工作遇到一个需求,主表、明细表需要用看板的模式显示,主表显示内容,从表显示表明细,如下图所示,需要每个表右键菜单独立选择当前明细内容

Pas程序

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, 
Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Data.DB, Data.Win.ADODB, Vcl.ComCtrls, Vcl.Menus;
type TForm1 = class(TForm) FlowPanel1: TFlowPanel; toppanel: TPanel; Button1: TButton; ADOQuery1: TADOQuery; ADOQuery2: TADOQuery; PopupMenu1: TPopupMenu; N11111: TMenuItem; N1: TMenuItem; ScrollBox1: TScrollBox; procedure Button1Click(Sender: TObject); procedure N1Click(Sender: TObject); procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure N11111Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer; var Resize: Boolean); private { Private declarations } var panel: array of TPanel; //动态创建Panel lb: array of TLabel; //动态创建Label lv: array of TListView; //动态创建ListView ListView: TListView; //当前选中ListView count: Integer; //动态创建控件总数 public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var I: Integer; begin //查询所有区域 with ADOQuery1 do begin Close; SQL.Clear; SQL.Add('SELECT r.RegionID, r.RegionDescription FROM Region AS r WITH(NOLOCK)'); Open; end; if ADOQuery1.RecordCount > 0 then begin //设置数组大小 SetLength(panel, ADOQuery1.RecordCount); SetLength(lb, 4); SetLength(lv, ADOQuery1.RecordCount); //创建控件总数 count := ADOQuery1.RecordCount - 1; //拖动竖向滚动条内容跟随滚动 ScrollBox1.VertScrollBar.Tracking := True; //定位查询到第一条记录 ADOQuery1.First; for I := 0 to ADOQuery1.RecordCount - 1 do begin //动态创建Panel panel[I] := TPanel.Create(Self); panel[I].Name := 'pan' + IntToStr(I); panel[I].Width := 200; panel[I].Height := 180; panel[I].AlignWithMargins := True; panel[I].Margins.Top := 5; panel[I].Margins.Left := 5; panel[I].Margins.Right := 5; panel[I].Margins.Bottom := 5; panel[I].ShowCaption := False; panel[I].Parent := FlowPanel1; //动态创建Label lb[I] := TLabel.Create(Self); lb[I].Caption := '区域编号:'; lb[I].Left := 10; lb[I].Top := 10; lb[I].Parent := panel[I]; lb[I] := TLabel.Create(Self); lb[I].Name := 'bh' + IntToStr(I); lb[I].Caption := ADOQuery1.FieldByName('RegionID').AsString; lb[I].Left := 80; lb[I].Top := 10; lb[I].Parent := panel[I]; lb[I] := TLabel.Create(Self); lb[I].Caption := '区域名称:'; lb[I].Left := 10; lb[I].Top := 30; lb[I].Parent := panel[I]; lb[I] := TLabel.Create(Self); lb[I].Name := 'mc' + IntToStr(I); lb[I].Caption := ADOQuery1.FieldByName('RegionDescription').AsString; lb[I].Left := 80; lb[I].Top := 30; lb[I].Parent := panel[I]; //动态创建Listview lv[I] := TListView.Create(Self); lv[I].ViewStyle := vsReport; //设置显示模式 lv[I].RowSelect := True; //行选中 lv[I].GridLines := True; //表格线 lv[I].DoubleBuffered := True; //不设置ListView滚动时会煽动 lv[I].Name := 'tv' + IntToStr(I); lv[I].Top := 50; lv[I].Height := panel[I].Height - 50; lv[I].Width := panel[I].Width; lv[I].Parent := panel[I]; //创建ListView列 with lv[I].Columns.Add do begin Caption := '编号'; Width := 50; end; with lv[I].Columns.Add do begin Caption := '名称'; Width := 120; end; //根据查询添加内容 lv[I].Items.BeginUpdate; with ADOQuery2 do begin Close; SQL.Clear; SQL.Add('SELECT t.TerritoryID, t.TerritoryDescription FROM Territories AS t WITH(NOLOCK) '); SQL.Add('WHERE t.RegionID=:RegionID'); Parameters.ParamByName('RegionID').Value := ADOQuery1.FieldByName('RegionID').AsString; Open; end; if ADOQuery2.RecordCount > 0 then begin ADOQuery2.First; while not ADOQuery2.Eof do begin with lv[I].Items.Add do begin Caption := ADOQuery2.FieldByName('TerritoryID').AsString; SubItems.Add(ADOQuery2.FieldByName('TerritoryDescription').AsString); end; ADOQuery2.Next; end; end; lv[I].Items.EndUpdate; //绑定鼠标点击事件,取当前点击ListView lv[I].OnMouseDown := ListViewMouseDown; //增加右键菜单 lv[I].PopupMenu := PopupMenu1; ADOQuery1.Next; end; end; end; procedure TForm1.FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer; var Resize: Boolean); begin //窗体更改大小重新设置FlowPanel宽度,不设置FlowPanel不会动态调整 FlowPanel1.width := Self.clientwidth end; //关闭释放动态创建 procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); var i: Integer; begin if count > 0 then begin for i := 0 to count do begin lv[i].Free; lb[i].Free; panel[i].Free; end; end; end; //当前选中ListView procedure TForm1.ListViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin ListView := (Sender as TListView); end; //获取全部内容 procedure TForm1.N11111Click(Sender: TObject); var str: string; I: Integer; begin if ListView = nil then Exit; if ListView.Items.Count < 0 then Exit; if ListView.Selected = nil then Exit; for I := 0 to ListView.Items.Count - 1 do begin str := str + ListView.Items[I].Caption + '-' + ListView.Items[I].SubItems[0] + #13; end; ShowMessage(str); end; //当前选中 procedure TForm1.N1Click(Sender: TObject); var str: string; id: string; begin if ListView = nil then Exit; if ListView.Items.Count < 0 then Exit; if ListView.Selected = nil then Exit; id := StringReplace(ListView.Name, 'tv', '', [rfReplaceAll]); str := lb[StrToInt(id)].Caption; str := str + ':' + ListView.Selected.Caption + '-' + ListView.Selected.SubItems[0]; ShowMessage(str); end; end.

 当前选中

查询所有

 Demo下载

原文地址:https://www.cnblogs.com/liessay/p/14927147.html