各位帮帮忙!(100分)

  • 主题发起人 主题发起人 lostlastlove
  • 开始时间 开始时间
L

lostlastlove

Unregistered / Unconfirmed
GUEST, unregistred user!
unit DateEdit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Mask;
type
TValidateErrorEvent = procedure (Sender: TObject
var Handled : Boolean) of object;
TDateEdit = class(TMaskEdit)
private
protected
FOnValidate : TNotifyEvent;
FOnValidateError : TValidateErrorEvent;
public
constructor Create(AOwner: TComponent)
override;
procedure ValidateEdit
override;
published
property OnValidate : TNotifyEvent read FOnValidate write FOnValidate;
property OnValidateError : TValidateErrorEvent read FOnValidateError write FOnValidateError;
end;

procedure Register;
implementation

constructor TDateEdit.Create(AOwner: TComponent);
begin
inherited;
EditMask :='!0000/00/00;1
';
{Font.Name:='宋体';
Font.Size:=9;}
end;

procedure TDateEdit.ValidateEdit;
var Handled : Boolean;
begin
if Assigned(OnValidate) then
OnValidate(self)
else
begin
if Text <> ' / / ' then
begin
try
Text := FormatDateTime('dd/mm/yyyy',StrToDate(Text));
except
begin
Handled := False;
if Assigned(OnValidateError) then
OnValidateError(self,Handled);
if not Handled then
Raise Exception.Create('Invalid input value, use escape key to abandon changes.');
end;
end;
end;
end;
end;

procedure Register;
begin
RegisterComponents('ControlX', [TDateEdit]);
end;
end.

上面是一个DateEdit控件的原代码,继承自TMaskEdit, 添加了两个事件:
OnValidate和OnValidateError,我在程序设计的过程中用到两个DateEdit控件,
由于程序的需要,我要检验输入的日期值的有效性,比如日期不能
不能为未来的日期,还有后面的日期必须大于前面的日期等情况,并且及时给出提示信息。
在程序中我必须提前捕获错误,并且将出错信息在状态栏显示,而不是跳出错误提示框。

实现代码:
{————————————————————————————————————————}
procedure TMainForm.edtStartDateValidate(Sender: TObject);
begin
inherited;
with (Sender as TDateEdit) do
begin
if strtoDate(Text)>Today then
begin
DispErr('Can''t input a future date!');
Setfocus;
abort;
end;
end;
end;
procedure TMainForm.edtEndDateValidateError(Sender: TObject;
var Handled: Boolean);
begin
inherited;
(Sender as TDateEdit).SetFocus
DispErr('Invalid Date!');
Handled:=true;
Abort
end;
{————————————————————————————————————————}
//Today:Tdatetime,为当前日期!
//DispErr(string:string)为我在基类中定义的一方法,它在状态栏显示string内容!

但是上面的代码只能提示‘Can't input a future date!’,而当输入非法日期如
‘01/22/2001’时则不能提示‘Invalid Date!’也就是edtEndDateValidateError事件里
的代码并没有执行!

请教各位,我该如何实现?


 
请试一试将 Abort 语句去掉。
 
把 inherited;放到后面试一试
 
发贴前就试过了,不行!
 
对 EXE 文件试验一下,Debug 状态和 EXE 状态不一样
 
运行EXE也不行!
 
各位大哥帮帮忙啊!小妹一定给分!
 
刚才没看仔细,根据 TDateEdit.ValidateEdit 的逻辑:

if Assigned(OnValidate) then
OnValidate(self)
else begin
...
end;
当OnValidate事件被赋予了处理过程时,就不再执行 else 的部分,也就不会触发
OnValidateError 事件,而你已经对 OnValidate 事件赋值了,因此就不会执行你
OnValidateError 事件处理过程中的代码。
所以你只能在 OnValidate 和 OnValidateError 事件中选一个,在其中处理所有异常
情况。同时使用则 OnValidateError 实际无效。
 
那我怎么办?难道还要把在DateEdit里写的代码再在OnValidate事件里重写一边吗?假如我
希望只用OnValidateError时间呢,怎么实现?
 
改一下TDateEdit.ValidateEdit吧:
procedure TDateEdit.ValidateEdit;
var Handled : Boolean;
begin
if Text <> ' / / ' then
begin
try
if Assigned(OnValidate) then
OnValidate(self);
Text := FormatDateTime('dd/mm/yyyy',StrToDate(Text));
except
begin
Handled := False;
if Assigned(OnValidateError) then
OnValidateError(self,Handled);
if not Handled then
Raise Exception.Create('Invalid input value, use escape key to abandon changes.');
end;
end;
end;
end;
应该可以。
 
TO:BBKXJY:
  非常感谢你的回答,不过DATEEDIT组件是放在网络上公用的,我不能更改原代码,
除非我们经理说改才行!
  所以请帮我考虑一下不动DATEEDIT代码的办法!
 
那这样吧,重写OnValidate事件处理过程:
procedure TMainForm.edtStartDateValidate(Sender: TObject);
var
tmpdate: TDatetime;
begin
inherited;
with (Sender as TDateEdit) do
if Text <> ' / / ' then
begin
try
tmpdate := strtoDate(Text);
if tmpdate > Today then
begin
DispErr('Can''t input a future date!');
Setfocus;
Exit;
end;
Text := FormatDateTime('dd/mm/yyyy',tmpdate);
except
DispErr('Invalid date!');
SetFocus;
end

end;
end;
这样 TDateEdit.ValidateEdit 的很多代码就没法被重用了,也许你可以说服你经理 :)
另,是不是用了窗体继承,这么多的 inherited?
 
对了,当前的窗体都是从BaseForm继承来的,BaseForm里定义了很多基本的方法和过程,
为了保证各个模块的统一性,必须继承!

我就是想不通为什么我的OnValidateError事件为什么不能响应,
经你一点,现在明白了!
最后在问你一点:
TEditDate.VaildtateEdit这个过程在什么时候被调用?
 
ValidateEdit 是 TCustomMaskEdit 中引入的虚拟方法。帮助中说的比较详细:
用户每次击键后及焦点将离开编辑框时该方法都会被调用。要更了解就看源码吧。
 
THANK YOU!!!
 
SORRY!
忘记给分了!
 
后退
顶部