使用TField.OnValidate 事件。这是在EditMask 被验证之后,但在数据实际写入记录缓冲区之前调用的。这允许您在完成基本字符验证后进行更广泛的验证。
事件将Sender参数中正在验证的字段接收到TFieldNotifyEvent:
TFieldNotifyEvent = procedure(Sender: TField) of Object;
您可以执行您需要执行的操作来验证该事件中的数据,并在新值不满足您的时间跨度要求时引发异常。例如,如果在字段中输入少于 2 个字符,以下内容将引发异常:
procedure TForm4.ClientDataSet1ClientDataSet1Field1Validate(Sender: TField);
begin
if not (Length(Trim(Sender.AsString)) > 1) then
raise Exception.Create('Invalid length for field content.');
end;
另一种方法是改用TDBGrid.OnColExit 事件,但我更喜欢将数据验证代码与数据库内容更直接地保存在一起,而不是将其绑定到用户界面的特定部分。 (将其保存在数据库中,即使您稍后改变主意并从使用网格切换到使用单独的表单进行记录维护,或者当您从代码而不是 UI 设置字段值时,它也会自动执行。)
就实际验证数据本身而言,最简单的方法是使用TRegEx,如果它在您使用的Delphi 版本中可用。像这样的表达式应该可以工作:
var
FoundMatch: Boolean;
TimeStr: string;
begin
TimeStr := Sender.AsString;
FoundMatch := TRegEx.IsMatch(TimeStr,
'\A([0-1][0-9]|[2][0-3]):[0-5][0-9]\z', [roMultiLine]);
if not FoundMatch then
raise Exception.CreateFmt('Invalid time value %s', [TimeStr]);
end;
如果您的 Delphi 版本中没有 TRegEx,您可以在 Regular-Expressions.info 网站上找到免费的开源 TPerlRegEx;它是当前 Delphi 版本中用于其正则表达式支持核心的代码。在这种情况下,这段代码也应该可以工作:
var
Regex: TPerlRegEx;
FoundMatch: Boolean;
TimeStr: string;
begin
TimeStr := Sender.AsString;
Regex := TPerlRegEx.Create;
try
Regex.RegEx := '\A([0-1][0-9]|[2][0-3]):[0-5][0-9]\z';
Regex.State := [preNotEmpty];
Regex.Subject := TimeStr;
FoundMatch := Regex.Match;
if not FoundMatch then
raise Exception.CreateFmt('Invalid time value %s', [TimeStr]);
finally
Regex.Free;
end;
end;