DBGrid 的 PickList的自动弹出(50分)

  • 主题发起人 hfghfghfg
  • 开始时间
H

hfghfghfg

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, Grids, DBGrids;
type
myGrid = class(TCustomGrid)
end;
type
myInplaceEditList = class(TInplaceEditList)
end;
const
My_Msg_display = wm_user + 400;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DataSource1: TDataSource;
ADODataSet1: TADODataSet;
ADODataSet1f1: TStringField;
ADODataSet1f2: TStringField;
procedure FormCreate(Sender: TObject);
procedure DBGrid1ColEnter(Sender: TObject);
procedure display_from_msg(var Message: TMessage); message My_Msg_display;
procedure ADODataSet1AfterScroll(DataSet: TDataSet);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
ADODataSet1.close;
ADODataSet1.CreateDataSet;
ADODataSet1.Open;
end;

procedure TForm1.DBGrid1ColEnter(Sender: TObject);

begin
postmessage(handle, My_Msg_display, 0, 0);
end;

procedure TForm1.display_from_msg(var Message: TMessage);
var
i: integer;
begin
if TstringGrid(DBGrid1).Col = 2 then
myInplaceEditList(myGrid(DBGrid1).InplaceEditor).DropDown;
end;

procedure TForm1.ADODataSet1AfterScroll(DataSet: TDataSet);
begin
postmessage(handle, My_Msg_display, 0, 0);

end;

end.



object Form1: TForm1
Left = 192
Top = 103
Width = 676
Height = 303
ActiveControl = DBGrid1
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object DBGrid1: TDBGrid
Left = 0
Top = 156
Width = 668
Height = 120
Align = alBottom
DataSource = DataSource1
Options = [dgEditing, dgAlwaysShowEditor, dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit]
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
OnColEnter = DBGrid1ColEnter
Columns = <
item
Expanded = False
FieldName = 'f1'
Width = 153
Visible = True
end
item
Expanded = False
FieldName = 'f2'
PickList.Strings = (
'12'
'34'
'56')
Width = 228
Visible = True
end>
end
object DataSource1: TDataSource
DataSet = ADODataSet1
Left = 120
Top = 88
end
object ADODataSet1: TADODataSet
AfterScroll = ADODataSet1AfterScroll
Parameters = <>
Left = 48
Top = 32
object ADODataSet1f1: TStringField
FieldName = 'f1'
Size = 100
end
object ADODataSet1f2: TStringField
FieldName = 'f2'
Size = 100
end
end
end
 
稍微说一下思路:
有两种方式来实现你这个功能
1、就是向你这个样子,查找VCL代码,能够知道DBGrid的PickList是通过TDBGridInplaceEdit.DropDown;来实现的,但是,很遗憾,TDBGridInplaceEdit定义在implementation里面,除非你去修改DBGrid.pas文件,否则是不行的。——此路基本不通。

2、就是模拟按键或者鼠标按键来实现功能
TDBGridInplaceEdit.DoDropDownKeys和TDBGridInplaceEdit.MouseDown两个函数说明了是那些按键或者鼠标。
VK_UP, VK_DOWN 和Alt和鼠标左键。
 
以上是我的一种写法,d6下调试通过。
//只是写的有点怪,非常规写法。
//贴出来,给大家玩。
 
yzhshi:
我写的代码是可以运行的。//不需修改DBGrid.pas

原因:

protected
。。。。
property InplaceEditor: TInplaceEdit read FInplaceEdit;


我通过
type
myInplaceEditList = class(TInplaceEditList)
end;
访问 //myInplaceEditList(myGrid(DBGrid1).InplaceEditor).DropDown;





 
还有:

TInplaceEditList = class(TInPlaceEdit)
private
FButtonWidth: Integer;
FPickList: TCustomListbox;
FActiveList: TWinControl;
FEditStyle: TEditStyle;
FDropDownRows: Integer;
FListVisible: Boolean;
FTracking: Boolean;
FPressed: Boolean;
FPickListLoaded: Boolean;
FOnGetPickListitems: TOnGetPickListItems;
FOnEditButtonClick: TNotifyEvent;
function GetPickList: TCustomListbox;
procedure CMCancelMode(var Message: TCMCancelMode); message CM_CancelMode;
procedure WMCancelMode(var Message: TMessage); message WM_CancelMode;
procedure WMKillFocus(var Message: TMessage); message WM_KillFocus;
procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message wm_LButtonDblClk;
procedure WMPaint(var Message: TWMPaint); message wm_Paint;
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SetCursor;
protected
procedure BoundsChanged; override;
function ButtonRect: TRect;
procedure CloseUp(Accept: Boolean); dynamic;
procedure DblClick; override;
procedure DoDropDownKeys(var Key: Word; Shift: TShiftState); virtual;
procedure DoEditButtonClick; virtual;
procedure DoGetPickListItems; dynamic;
procedure DropDown; dynamic;///////////////////////////
 
你使用的是Delphi6,怪不得,我使用的是Delphi5,在Delphi5中的实现和Delphi7的实现是不一样的。
Delphi5中只有,TDBGridInplaceEdit,继承自Grid.pas的TInplaceEdit。
但是DropDown属性是在TDBGridInplaceEdit中才有的,但是TDBGridInplaceEdit声明在implementation下,所以我说不能实现。
 
还有,因为InplaceEditor在DBGrid中和DropDown在TInplaceEditList中均为Protect的,所以你使用类的方式实现是正常的。
同时由于这个 TInplaceEditList 是DBGrid的属性而不是Column的属性,所以只好使用你的办法来实现了。。。

另外,如果用一下的方法来实现,就必须首先对FDataList进行初始化,可惜的很,那个初始化部分还是在implementation部分。我注释掉的那部分代码不行。
所以你迂回选择的那个办法看出来也是不得已而为之的,已经很不容易了。

DBGrid1.SelectedIndex := 1;
// TmyInplaceEditList(TmyGrid(DBGrid1).InplaceEditor).UpdateContents;
TmyInplaceEditList(TmyGrid(DBGrid1).InplaceEditor).DropDown;
 
更新

procedure TForm1.display_from_msg(var Message: TMessage);
var
i: integer;
begin
if TstringGrid(DBGrid1).Col = 2 then
begin
DBGrid1.Options := DBGrid1.Options + [dgAlwaysShowEditor];
myInplaceEditList(myGrid(DBGrid1).InplaceEditor).DropDown;
DBGrid1.Options := DBGrid1.Options - [dgAlwaysShowEditor];
end;
end;
 
既然这样,那么就不用消息了吧?
如下即可,当然两个一摸一样,可以写成函数的。
还有,使用SelectedIndex更好一些,不用强制转换了,且即使强制转换,也不要转换成TStringGrid,使用TCustomGrid,col是TCustomGrid的属性,且DBGrid是从TCustomGrid继承的,StringGrid只是TDBGrid的堂侄子。^_^

TStringGrid->TDrawGrid->TCustomDrawGrid->TCustomGrid
TDBGrid->TCustomDBGrid->TCustomGrid

procedure TForm1.DBGrid1ColEnter(Sender: TObject);
begin
if DBGrid1.SelectedIndex = 1 then
begin
DBGrid1.Options := DBGrid1.Options + [dgAlwaysShowEditor];
myInplaceEditList(myGrid(DBGrid1).InplaceEditor).DropDown;
DBGrid1.Options := DBGrid1.Options - [dgAlwaysShowEditor];
end;
end;

procedure TForm1.Query1AfterScroll(DataSet: TDataSet);
begin
if DBGrid1.SelectedIndex = 1 then
begin
DBGrid1.Options := DBGrid1.Options + [dgAlwaysShowEditor];
myInplaceEditList(myGrid(DBGrid1).InplaceEditor).DropDown;
DBGrid1.Options := DBGrid1.Options - [dgAlwaysShowEditor];
end;
end;
 
yzhshi:
你说到对!
 
接受答案了.
 

Similar threads

顶部