这是我的情况: 我有一个任务,我需要使用TClientDataSet进行一些操作(是的,我必须使用这个特定的组件)。用户将能够编辑TClientDataSet中的数据,因此我使用连接到TDataSource的TDBGrid,它连接到我的TClientDataSet。
我需要做的是防止用户根据其值离开单元格(将焦点移动到程序中的其他位置)。有效值是从00:00到23:59的时间。它不能为空或有空白字符。我正在使用TClientDataSet字段的EditMask属性,因此可以直接以正确的格式输入。
实施例: 如果用户在单元格中键入29:00,然后尝试移动到另一个单元格(或另一个组件),我希望能够停止它,并让他在单元格中输入一些其他有效值(如15:00) ),然后他可以离开它并做其他事情(比如编辑另一个单元格)。
进行此类验证的选项有哪些?我正在使用Borland Delphi 7。
感谢。
答案 0 :(得分:4)
使用TField.OnValidate事件。在验证EditMask
之后但在数据实际写入记录缓冲区之前调用。这使您可以在完成基本字符验证后进行更广泛的验证。
该事件会在Sender
的{{1}}参数中收到要验证的字段:
TFieldNotifyEvent
您可以执行验证该事件中数据所需的操作,并在新值不符合时间跨度要求时引发异常。例如,如果在字段中输入的字符少于2个,则以下内容将引发异常:
TFieldNotifyEvent = procedure(Sender: TField) of Object;
另一种方法是使用TDBGrid.OnColExit事件,但我更喜欢将数据验证代码更直接地保存在数据库内容中,而不是将其绑定到用户界面的特定部分。 (将数据保存在数据库中会使其自动执行,即使您以后改变主意并从使用网格切换到使用单独的表单进行记录维护,或者从代码而不是UI设置字段值时。)
就实际验证数据本身而言,最简单的方法是使用TRegEx,如果它在您正在使用的Delphi版本中可用。像这个表达式的东西应该有效:
procedure TForm4.ClientDataSet1ClientDataSet1Field1Validate(Sender: TField);
begin
if not (Length(Trim(Sender.AsString)) > 1) then
raise Exception.Create('Invalid length for field content.');
end;
如果您的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;
,您可以在Regular-Expressions.info网站找到免费的开源TRegEx
;它是当前Delphi版本中正则表达式支持核心中使用的代码。在这种情况下,此代码也应该起作用:
TPerlRegEx