即使在编辑框中输入整个值之前,也会进行错误检查

时间:2013-10-09 20:27:43

标签: delphi

我在表单上有两个编辑框,一个用于最小值,另一个用于用户需要输入的最大值。我希望在用户输入值时捕获可能的错误。一个可能的错误是最大值小于最小值。如果发生这种情况,我会提示错误消息。但是,即使用户想要在最小框中输入5并且在最大框中输入100,如果用户在最大框中输入100的“1”,它也会显示错误消息在min框中输入了5。如何允许用户在出现错误消息之前输入整个值?

这是我的代码(我也捕获了其他错误,但只有max< min错误似乎受到影响):

procedure TfrmAnalysisOptions.lbleConstraintsMaxChange(Sender: TObject);
var
  I: integer;
  Val, ValidEntry: string;
  Chr: char;
  RangeMin, RangeMax: Double;
  const Allowed = ['0'..'9', '.'];
begin

  Val := lbleConstraintsMax.Text;

      //initialize values    
  ValidEntry := '';
  ConstraintsMaxChange := '';

  //value can contain only numerals, and "."
    for I := 1 to Length(Val) do
     begin
       Chr := Val[I];
       if not (Chr in Allowed) then
       begin
     MessageDlgPos('The value entered for the max value of the ' +
               'constraint must contain only a numeral, a decimal ' +
               'point or a negative sign.',
            mtError, [mbOK], 0, 300, 300);
     Exit;

       end
       else ValidEntry := 'OK'; //validity check for this part

     end;

     //max value cannot be zero or less than the min value
    if not TryStrToFloat(Val, RangeMax) then Exit
    else if RangeMax = 0 then
    begin
       MessageDlg('Max value cannot be zero.', mtError, [mbOK], 0);
       Exit;
    end
    else if not TryStrToFloat(lbleConstraintsMin.Text, RangeMin) then Exit
    else if RangeMax < RangeMin then
      begin
    MessageDlgPos('Max value cannot be less than Min value.',
           mtError, [mbOK], 0, 300, 300);
    Exit;
      end

    else if (RangeMax < 0) then
      begin
    MessageDlgPos('A constraint cannot be negative.',
              mtError, [mbOK], 0, 300, 300);
    Exit;
      end

    //final validity check
    else if ValidEntry = 'OK' then ConstraintsMaxChange := 'OK'
    else MessageDlgPos('There was an unexpected problem with the ' +
               'value entered in the max constraints box.',
            mtError, [mbOK], 0, 300, 300);

end;

2 个答案:

答案 0 :(得分:5)

每次修改编辑控件的内容时都会触发OnChange事件。虽然这是过滤掉无效字符的合适位置,但它不是验证数值的合适位置。无法预测用户打算输入的号码,无论是5505005,000,其中每个号码可能是可接受的,也可能是不可接受的。

解决方案1 ​​:在填写完这些编辑控件并且用户尝试进入下一步(保存,继续,加载,启动等)后执行此检查。

解决方案2 :您可以在这些控件旁边显示一个标签,而不是显示消息框,该标签显示&#34;无效条目&#34;同时保持同样的逻辑。这样,用户就不会遇到许多消息框。

解决方案3 :使用OnExit事件代替OnChange。请注意,这不会完全解决您的问题,但会将其最小化。当焦点离开控件时会触发此事件。

解决方案4 与解决方案2类似,使用OnChangeOnExit来控制用户可能按下的按钮的Enabled属性。< / p>

解决方案5 与解决方案4类似,使用操作并更改该特定操作的Enabled属性。然后,无法点击用户可能按下的任何按钮。


另一方面,当您过滤掉无效字符时,忽略这些字符会更加优雅,而不是让它们首先进入控件,而不是弹出一条消息。您可以使用OnKeyPress事件代替,或使用TMaskEdit

来完成此操作

答案 1 :(得分:1)

作为OnExit或OnChange的替代方法,我可以建议一种面向对象的模式方法:

  1. 定义模型对象。 TMyBusinessModelObject = class ....
  2. 在View对象中定义一个将数据复制到模型对象的函数。
  3. 在模型对象中进行验证。
  4. 如果有意义,请在需要时启动验证,即模式对话框关闭时。如果您需要在屏幕上显示颜色代码,例如图像或状态指示器,请使用OnExit个事件。
  5. 编写单元测试,以便您了解模型对象,并且您的viewmodel或控制器对象可以工作,并且您的业务逻辑可以正常工作。
  6. 其次,甚至比编写代码来阻止无效字符的TMaskEditTEdit更好,JVCL中有专门为数字输入设计的控件,包括允许您输入约束的控件在控制层面。

    Delphi是一个面向组件的RAD工具,当你像一个人一样使用它时,当你从一开始就避免使用代码隐藏形式(Big Ball of Mud)时,你就不会有一个巨大的混乱以后清理。 (一个相当可悲的事实是,标准德尔菲的做法是做最简单的事情,可能有效,并建立一个巨大的泥球,没有OOP。)