delphi - 如何防止用户根据其值离开 DBGrid 的单元格

标签 delphi validation delphi-7 tclientdataset dbgrid

这是我的情况:
我有一个任务,我需要使用 TClientDataSet 进行一些操作(是的,我必须使用这个特定的组件)。用户将能够编辑 TClientDataSet 中的数据,因此我使用连接到 TDataSource 的 TDBGrid,TDataSource 连接到我的 TClientDataSet。

我需要做的是防止用户根据它的值离开单元格(将焦点移动到程序中的其他地方)。有效值是从 00:00 到 23:59 的时间。它不能为空或包含空白字符。我正在使用 TClientDataSet 字段的 EditMask 属性,因此很容易以正确的格式直接键入。

例子:
如果用户在单元格中输入 29:00,然后尝试移动到另一个单元格(或另一个组件),我希望能够停止该操作,并让他在单元格中输入一些其他有效值(如 15:00 ),然后他可以离开它并做其他事情(比如编辑另一个单元格)。

进行这种验证的选项有哪些?我正在使用 Borland Delphi 7。

谢谢。

最佳答案

使用 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事件,但我更喜欢将数据验证代码与数据库内容更直接地保存在一起,而不是将其绑定(bind)到用户界面的特定部分。 (将其保存在数据库中,即使您稍后改变主意并从使用网格切换到使用单独的表单进行记录维护,或者当您从代码而不是 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;

如果 TRegEx在您的 Delphi 版本中不可用,您可以找到免费的开源 TPerlRegExRegular-Expressions.info网站;它是当前 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;

关于delphi - 如何防止用户根据其值离开 DBGrid 的单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24090413/

相关文章:

mysql - 使用 Delphi 存储 SQL 字段名称和一般 SQL 用法

delphi - 如何防止控件被添加到从TCustomPanel派生的组件中?

jquery - 如何阻止文本框输入 Unicode 字符?

delphi - 请说明包装用途

德尔福。反转光标颜色

delphi - 如何同步父/子进程执行?

Delphi VirtualStringTree OnGetHint

不需要 Laravel 验证,但仍然像需要一样返回

javascript - 如何使用 JS/jQuery 验证两个下拉字段中的时间值?

delphi - Lazarus 中是否有类似于 Delphi "Use debug DCUs"的选项