下拉选择框

unit ynSearch;

interface

uses
SysUtils, Windows, DB, DBClient, Classes, ExtCtrls, Dialogs, StdCtrls, Provider, DBGrids, Controls;

type
TYNSearch = class(TCustomComboBox)
private
FDataSet: TDataSet; // 数据集
FListDataSet: TDataSet; // 下拉数据集
FDataField: string;
FDataFieldCN: string;
FListFields: string; // f1,f2
FListFieldsCN: string; // f1,f2
FPanelWidth: integer;
FPanelHeight: integer;
procedure DropDown(Sender: TObject);
procedure Change(Sender: TObject);
procedure Filter;
procedure AdjustDropDownForm(AControl: TControl; HostControl: TControl);
protected
public
constructor Create(Owner: TComponent); override;
published
property DataSet: TDataSet read FDataSet write FDataSet;
property ListDataSet: TDataSet read FListDataSet write FListDataSet;
property DataField: string read FDataField write FDataField;
property DataFieldCN: string read FDataFieldCN write FDataFieldCN;
property ListFields: string read FListFields write FListFields;
property ListFieldsCN: string read FListFieldsCN write FListFieldsCN;
property PanelWidth: Integer read FPanelWidth write FPanelWidth default 380;
property PanelHeight: Integer read FPanelHeight write FPanelHeight default 150;
end;

type
TPopupPanel = class(TCustomPanel)
private
procedure griddblclick(sender: TObject);
protected
public
DSP: TDataSetProvider;
CDS: TClientDataSet;
DS: TDataSource;
Grid: tdbgrid;
dataset: TDataSet;
listdataset: TDataSet;
datafield: string;
datafieldcn: string;
listfields: string;
listfieldscn: string;
panel integer;
panelheight: integer;
search: integer;
constructor create(owner: TComponent); override;
procedure createcols;
end;

var
PopupPanel: TPopupPanel;

procedure register;

implementation

procedure register;
begin
RegisterComponents('Standard', [TYNSearch]);
end;

procedure TYNSearch.AdjustDropDownForm(AControl: TControl; HostControl: TControl);
var
WorkArea: TRect;
HostP, PDelpta: TPoint;
begin
SystemParametersInfo(SPI_GETWORKAREA, 0, @WorkArea, 0);
HostP := HostControl.ClientToScreen(Point(0, 0));
PDelpta := AControl.ClientToScreen(Point(0, 0));
AControl.Left := HostP.x;
AControl.Top := HostP.y + HostControl.Height + 1;
if (AControl.Width > WorkArea.Right - WorkArea.Left) then
AControl.Width := WorkArea.Right - WorkArea.Left;
if (AControl.Left + AControl.Width > WorkArea.Right) then
AControl.Left := WorkArea.Right - AControl.Width;
if (AControl.Left < WorkArea.Left) then
AControl.Left := WorkArea.Left;

if (AControl.Top + AControl.Height > WorkArea.Bottom) then
begin
if (HostP.y - WorkArea.Top > WorkArea.Bottom - HostP.y - HostControl.Height) then
AControl.Top := HostP.y - AControl.Height;
end;

if (AControl.Top < WorkArea.Top) then
begin
AControl.Height := AControl.Height - (WorkArea.Top - AControl.Top);
AControl.Top := WorkArea.Top;
end;

if (AControl.Top + AControl.Height > WorkArea.Bottom) then
begin
AControl.Height := WorkArea.Bottom - AControl.Top;
end;

end;

{ TYNSearch }

procedure TYNSearch.Change(Sender: TObject);
begin
if PopupPanel = nil then
begin
PopupPanel := TPopupPanel.create(self);
if self.DataSet <> nil then
PopupPanel.dataset := Self.DataSet;
PopupPanel.listdataset := self.ListDataSet;
PopupPanel.datafield := self.DataField;
PopupPanel.datafieldcn := self.DataFieldCN;
PopupPanel.listfields := self.ListFields;
PopupPanel.listfieldscn := self.ListFieldsCN;
PopupPanel.panelwidth := Self.PanelWidth;
PopupPanel.panelheight := self.PanelHeight;
PopupPanel.search := Integer(self);

PopupPanel.createcols;
end;

if not PopupPanel.Visible then
PopupPanel.Visible := True;
AdjustDropDownForm(PopupPanel, Self);
Self.Filter;
end;

constructor TYNSearch.Create(Owner: TComponent);
begin
inherited;
Self.OnChange := change;
self.OnDropDown := DropDown;

end;

procedure TYNSearch.DropDown(Sender: TObject);
begin
Change(nil);
end;

constructor TPopupPanel.create(owner: TComponent);
begin
inherited;
Self.BevelOuter := bvnone;
self.Caption := '';
self.Width := Self.panelwidth;
self.Height := Self.panelheight;

CDS := TClientDataSet.Create(Self);
DSP := TDataSetProvider.Create(self);
DS := TDataSource.Create(self);
DSP.DataSet := listdataset;
DS.DataSet := CDS;
CDS.Data := DSP.Data;

Grid := TDBGrid.Create(Self);
Grid.Align := alClient;
Grid.DataSource := DS;
grid.ReadOnly := True;
Grid.Options := Grid.Options + [dgRowSelect];
grid.OnDblClick := griddblclick;

end;

procedure TPopupPanel.createcols;
var
en, cn: TStringList;
i, k: integer;
begin
en := TStringList.Create;
cn := TStringList.Create;
try
en.Delimiter := ',';
en.DelimitedText := listfields;
cn.Delimiter := ',';
cn.DelimitedText := listfieldscn;
for i := 0 to Grid.Columns.Count - 1 do
begin
for k := 0 to en.Count - 1 do
begin
if Grid.Columns[i].FieldName = en[k] then
begin
Grid.Columns[i].Title.Caption := cn[k];
end
else
begin
Grid.Columns[i].Visible := False;
end;
end;
end;
finally
en.Free;
cn.Free;
end;
end;

procedure TPopupPanel.griddblclick(sender: TObject);
begin
if Self.dataset <> nil then
begin
self.dataset.Edit;
self.dataset.FieldByName(self.datafield).Text := Self.CDS.fieldbyname(Self.datafield).Text;
Self.dataset.Post;
end;

TYNSearch(self.search).Text := self.CDS.fieldbyname(self.datafieldcn).Text;

FreeAndNil(PopupPanel);
end;

procedure TYNSearch.Filter;
var
v: string;
ls: TStringList;
i: Integer;
begin
v := quotedstr('%' + Self.Text + '%');
PopupPanel.CDS.Filtered := False;
ls := TStringList.Create;
try
ls.Delimiter := ',';
ls.DelimitedText := Self.ListFields;
for i := 0 to ls.Count - 1 do
begin
if PopupPanel.CDS.Filter = '' then
begin
PopupPanel.CDS.Filter := ls[i] + ' like ' + v;
end
else
begin
PopupPanel.CDS.Filter := PopupPanel.CDS.Filter + ' or ' + ls[i] + ' like ' + v;
end;
end;
finally
ls.Free;
end;
PopupPanel.CDS.Filtered := True;
end;

end.

原文地址:https://www.cnblogs.com/hnxxcxg/p/6507154.html