简单地说,用tcxdbbuttonedit定制成一个能显示字符的日期控件.
首先建立此类.重构creat方法,在create加上 properties.OnButtonClick:=buttonclick;
在buttonclick中,呼叫一个日期控件,因为字段的格式是'yyyymmdd',在返回的时候就用formatdatatime格式化一下再赋给控件.使用此控件的时候,为了使它显示出日期格式,所以把它的editmask设置成!0000/00/00;1
从日期控件中返回字符型日期都没问题.问题出在删除这个控件里的值时,移到焦点到别处,就会出现'编辑值非法'的错误,这个问题花了一两天,最终找到一个解决办法:在控件的keyup里面,判断edittext是否为空,若为空,则 databinding.DataSource.DataSet.FieldByName(databinding.DataField).Clear;
然后在onvalidate事件里,判断editmask若不为空,且长度不等于10的时候,就
showmessage('输入的日期无效');
abort;编辑值非法的问题算是解决了,但问题又出现了.
当手动输入日期,再post的时候,就会出现:
'多步操作产生错误,请检查每一步值的状态.'真是晕死了,花了我三四天,弄得我烦死了,哪位高手能救救我啊一.如果有成熟的字符日期控件最好,请您发一个给我.不胜感激!
二.解决'编辑值非法'的问题有没有更好的问题.
三.最后,上面都不行,解决'多步操作产生错误,请检查每一步值的状态.'的问题,您也是我的救星啊.
首先建立此类.重构creat方法,在create加上 properties.OnButtonClick:=buttonclick;
在buttonclick中,呼叫一个日期控件,因为字段的格式是'yyyymmdd',在返回的时候就用formatdatatime格式化一下再赋给控件.使用此控件的时候,为了使它显示出日期格式,所以把它的editmask设置成!0000/00/00;1
从日期控件中返回字符型日期都没问题.问题出在删除这个控件里的值时,移到焦点到别处,就会出现'编辑值非法'的错误,这个问题花了一两天,最终找到一个解决办法:在控件的keyup里面,判断edittext是否为空,若为空,则 databinding.DataSource.DataSet.FieldByName(databinding.DataField).Clear;
然后在onvalidate事件里,判断editmask若不为空,且长度不等于10的时候,就
showmessage('输入的日期无效');
abort;编辑值非法的问题算是解决了,但问题又出现了.
当手动输入日期,再post的时候,就会出现:
'多步操作产生错误,请检查每一步值的状态.'真是晕死了,花了我三四天,弄得我烦死了,哪位高手能救救我啊一.如果有成熟的字符日期控件最好,请您发一个给我.不胜感激!
二.解决'编辑值非法'的问题有没有更好的问题.
三.最后,上面都不行,解决'多步操作产生错误,请检查每一步值的状态.'的问题,您也是我的救星啊.
{$IFDEF DELPHI6}
Variants,
{$ENDIF}
//{$IFDEF VCL}
Windows, Messages,
//{$ENDIF}
Classes, Controls, DB, DBCtrls, SysUtils,dialogs, forms,graphics,mask,stdctrls,
cxButtonEdit, cxCalc,ComCtrls,CommCtrl,
cxCalendar, cxCheckBox, cxClasses, cxContainer, cxCurrencyEdit, cxCustomData,
cxDataUtils, cxDB, cxDropDownEdit, cxEdit, cxHyperLinkEdit, cxImage,
cxImageComboBox, cxListBox, cxMaskEdit, cxMemo, cxMRUEdit, cxRadioGroup,
cxSpinEdit, cxTextEdit, cxTimeEdit,cxdbedit;
type
Efieldtype=(ctext,cdate,cdatetime); Tdatebuttonedit =class(TcxDBbuttonEdit)
private ffieldtype:Efieldtype;
protected public
constructor Create(AOwner: TComponent); overload; override;
constructor Create(AOwner: TComponent; AIsInplace: Boolean); reintroduce; overload;
procedure buttonclick(sender:TObject;AButtonIndex:integer);
procedure validate(Sender: TObject;var DisplayValue: Variant;
var ErrorText: TCaption; var Error: Boolean);
procedure klkeyup(Sender: TObject;var Key: Word; Shift: TShiftState);
published
property fieldtype:efieldtype read ffieldtype write ffieldtype default ctext;
property Anchors;
property AutoSize;
property BeepOnEnter;
property Constraints;
property DataBinding;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property ImeMode;
property ImeName;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property Properties;
property ShowHint;
property Style;
property StyleDisabled;
property StyleFocused;
property StyleHot;
property TabOrder;
property TabStop;
property Visible;
property OnClick;
{$IFDEF DELPHI5}
property OnContextPopup;
{$ENDIF}
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEditing;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
property OnEndDock;
property OnStartDock;
end;procedure Register;implementation
uses klmonthdate,publicunit;procedure Tdatebuttonedit.buttonclick(sender:TObject;AButtonIndex: Integer);
var
fklcalendar:Tfrmcalendar;
begin
if Properties.ReadOnly then exit;
fklcalendar:=Tfrmcalendar.Create(nil);
with fklcalendar do
begin
Parent:=self.Parent;
Top:=self.ClientOrigin.y+self.Height;
left:=self.ClientOrigin.x;
case ffieldtype of
ctext:
begin
fieldtype:='text';
if length(trim(self.Text))=10 then
monthcalendar1.Date:=strtodatetime(self.Text) else
monthcalendar1.Date:=now;
end;// cdate:
// cdatetime:
end;
showmodal;
if resultvalue<>'' then
self.DataBinding.DataSource.DataSet.FieldByName(self.DataBinding.DataField).Value:=resultvalue;
end;
freeandnil(fklcalendar);
end;constructor Tdatebuttonedit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
properties.OnButtonClick:=buttonclick;
style.BorderStyle:=ebs3d;
Properties.EditMask:='!0000/00/00;1';
OnKeyup:=klkeyup;
properties.onValidate:=Validate;
end;constructor Tdatebuttonedit.Create(AOwner: TComponent; AIsInplace: Boolean);
begin
inherited Create(AOwner);
properties.OnButtonClick:=buttonclick;
style.BorderStyle:=ebs3d;
self.Properties.EditMask:='!0000/00/00;1';
OnKeyup:=klkeyup;
properties.onValidate:=Validate;
end;
procedure Tdatebuttonedit.klkeyup(Sender: TObject;
var Key: Word; Shift: TShiftState);begin
if databinding.DataSource.DataSet.state in [dsinsert,dsedit] then
if (key=vk_delete) or (key=vk_back) then
begin
if (displayvalue=' - - ') or (strtimescount('_',displayvalue)=8)then
begin
databinding.DataSource.DataSet.FieldByName(databinding.DataField).Clear;
end;
end;end;procedure Tdatebuttonedit.validate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
begin if (length(trim(displayvalue))<10) or (pos('_',displayvalue)>0) then
begin if ((pos('_',displayvalue)=0) and (length(trim(displayvalue))>4)) or
((pos('_',displayvalue)>0) and (strtimescount('_',displayvalue)<>8)) then
begin
showmessage('输入日期无效');
abort;
end;
end;
end;procedure Register;
begin
RegisterComponents('Data Controls', [Tdatebuttonedit]);
end; {of Register}
{of uniut}
end.
谢谢啊!不过现在又发现一个问题,如果手动输入日期,结果保存在数据库里的是yyyy-mm-,而不是yyyymmdd,怎么会把掩码-也保存到数据库呢,并且后面的日期也被挤掉了.
{$IFDEF DELPHI6}
Variants,
{$ENDIF}
//{$IFDEF VCL}
Windows, Messages,
//{$ENDIF}
Classes, Controls, DB, DBCtrls, SysUtils,dialogs, forms,graphics,mask,stdctrls,
cxButtonEdit, cxCalc,ComCtrls,CommCtrl,
cxCalendar, cxCheckBox, cxClasses, cxContainer, cxCurrencyEdit, cxCustomData,
cxDataUtils, cxDB, cxDropDownEdit, cxEdit, cxHyperLinkEdit, cxImage,
cxImageComboBox, cxListBox, cxMaskEdit, cxMemo, cxMRUEdit, cxRadioGroup,
cxSpinEdit, cxTextEdit, cxTimeEdit,cxdbedit;
type
Efieldtype=(ctext,cdate,cdatetime); Tdatebuttonedit =class(TcxDBbuttonEdit)
private ffieldtype:Efieldtype;
protected public
constructor Create(AOwner: TComponent); overload; override;
constructor Create(AOwner: TComponent; AIsInplace: Boolean); reintroduce; overload;
procedure buttonclick(sender:TObject;AButtonIndex:integer);
procedure validate(Sender: TObject;var DisplayValue: Variant;
var ErrorText: TCaption; var Error: Boolean);
procedure klkeyup(Sender: TObject;var Key: Word; Shift: TShiftState);
published
property fieldtype:efieldtype read ffieldtype write ffieldtype default ctext;
property Anchors;
property AutoSize;
property BeepOnEnter;
property Constraints;
property DataBinding;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property ImeMode;
property ImeName;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property Properties;
property ShowHint;
property Style;
property StyleDisabled;
property StyleFocused;
property StyleHot;
property TabOrder;
property TabStop;
property Visible;
property OnClick;
{$IFDEF DELPHI5}
property OnContextPopup;
{$ENDIF}
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEditing;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
property OnEndDock;
property OnStartDock;
end;procedure Register;implementation
uses klmonthdate,publicunit;procedure Tdatebuttonedit.buttonclick(sender:TObject;AButtonIndex: Integer);
var
fklcalendar:Tfrmcalendar;
begin
if Properties.ReadOnly then exit;
fklcalendar:=Tfrmcalendar.Create(nil);
with fklcalendar do
begin
Parent:=self.Parent;
Top:=self.ClientOrigin.y+self.Height;
left:=self.ClientOrigin.x;
case ffieldtype of
ctext:
begin
fieldtype:= 'text ';
if length(trim(self.Text))=10 then
monthcalendar1.Date:=strtodatetime(self.Text) else
monthcalendar1.Date:=now;
end;// cdate:
// cdatetime:
end;
showmodal;
if resultvalue < > ' ' then
self.DataBinding.DataSource.DataSet.FieldByName(self.DataBinding.DataField).Value:=resultvalue;
end;
freeandnil(fklcalendar);
end;constructor Tdatebuttonedit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
properties.OnButtonClick:=buttonclick;
style.BorderStyle:=ebs3d;
Properties.EditMask:= '!0000/00/00;1 ';
OnKeyup:=klkeyup;
properties.onValidate:=Validate;
end;constructor Tdatebuttonedit.Create(AOwner: TComponent; AIsInplace: Boolean);
begin
inherited Create(AOwner);
properties.OnButtonClick:=buttonclick;
style.BorderStyle:=ebs3d;
self.Properties.EditMask:= '!0000/00/00;1 ';
OnKeyup:=klkeyup;
properties.onValidate:=Validate;
end;
procedure Tdatebuttonedit.klkeyup(Sender: TObject;
var Key: Word; Shift: TShiftState);begin
if databinding.DataSource.DataSet.state in [dsinsert,dsedit] then
if (key=vk_delete) or (key=vk_back) then
begin
if (displayvalue= ' - - ') or (strtimescount( '_ ',displayvalue)=8)then
begin
databinding.DataSource.DataSet.FieldByName(databinding.DataField).Clear;
end;
end;end;procedure Tdatebuttonedit.validate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
begin
if (length(trim(displayvalue)) <10) or (pos( '_ ',displayvalue) >0) then
begin
if ((pos( '_ ',displayvalue)=0) and (length(trim(displayvalue)) >4)) or
((pos( '_ ',displayvalue) >0) and (strtimescount( '_ ',displayvalue) < >8)) then
begin
showmessage( '输入日期无效 ');
abort;
end;
end;
if (length(trim(displayvalue))=10) and (pos('_',displayvalue)=0) then
try
databinding.DataSource.DataSet.FieldByName(databinding.DataField).asstring:=formatdatetime('yyyymmdd',strtodatetime(displayvalue));
except
showmessage('输入日期无效');
end;end;procedure Register;
begin
RegisterComponents( 'Data Controls ', [Tdatebuttonedit]);
end; {of Register}
{of uniut}
end.
加上一个判断就可以解决那个问题了,并且还能判断输入的日期是否有效.谢谢.这个控件就可以用了.