6

快速的问题我找不到任何信息。

在我正在创建的一个组件上,我有一个整数类型的值。

我只需要允许在 Object Inspector 中输入的值介于 0-10 之间,超出此范围的任何内容都应显示一条消息,说明输入的值不合适,然后将焦点返回给 Delphi Object Inspector .

例子:

TMyComponent = class(TComponent)
private
  FRangeVal: Integer;
  procedure SetRangeVal(const Value: Integer);
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
published
  property RangeVal: Integer read FRangeVal write SetRangeVal default 0;
end;

...

procedure SetRangeVal(const Value: Integer);
var
  OldValue: Integer;
begin
  OldValue := Value;
  if (Value < 0) or (Value > 10) then
  begin
    MessageDlg('Please enter a value between 0-10', mtError, [mbOK], 0);
    // FRangeVal := OldValue; ?? revert to the last value that worked
    // return focus back to property in Inspector ??
  end 
  else
  begin
    if Value <> FRangeVal then
    begin
      FRangeVal := Value;
    end;
  end;
end;

我是否需要提出某种我可能不知道的特殊内置异常?以上适用于我的消息框弹出,但对对象检查器中的罪魁祸首属性的关注丢失了,我必须重新单击它以再次更改值。如果输入的值不正确,我只想显示消息并返回焦点,以便快速输入新值。

PS,上面的代码是在网络浏览器中编写的,因此最初的问题显示我没有使用属性 RangeVal 的 setter SetRangeVal - 这只是一个打字错误。

4

3 回答 3

11

首先,如果您的属性只能包含 和 之间的值010请不要将其定义为模糊的整数属性;将其定义为具有已定义值范围的子类型:

type
  TMyComponentRangeValue = 0..10;

TMyComponent = class(TComponent)
private
  FRangeVal: TMyComponentRangeValue;
  procedure SetRangeVal(const Value: TMyComponentRangeValue);
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
published
  property RangeVal: TMyComponentRangeValue read FRangeVal 
    write SetRangeVal default 0;
end;

现在,您可以让编译器和 IDE 处理允许值的检查,而无需自己做任何事情。(如果输入了无效值,IDE 将处理异常并恢复到先前的值。)

procedure TMyComponent.SetRangeValue(const Value: TMyComponentRangeValue);
begin
  if Value <> FRangeValue then
    FRangeValue := Value;
end;
于 2013-01-01T23:56:50.407 回答
2

@KenWhite 回答了这个问题。
在无法处理定义自己的类型的情况下,您可以只引发错误而不是显示消息框。

于 2013-01-02T00:13:25.673 回答
2

这是您更正的代码(使用 Setter 方法)和Integer类型。

您可以在静默或异常 Setter 之间进行选择:

{$DEFINE SILENT_SETTER}

TMyComponent = class(TComponent)
private
  FRangeVal: Integer;
  procedure SetRangeVal(const Value: Integer);
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
published
  property RangeVal: Integer read FRangeVal write SetRangeVal default 0;
end;

...

procedure SetRangeVal(const Value: Integer);
begin
  // Range Checking
  if (Value < 0) or (Value > 10) then
{$IFDEF SILENT_SETTER}
    Exit;
{$ELSEIF}
    raise Exception.Create('Value out of Range');
{$ENDIF}

  // Store if needed
  if Value <> FRangeVal then
    FRangeVal := Value;
end;
于 2013-01-02T09:03:57.227 回答