编辑:下面的原始问题,但我现在修改它,因为我有一些代码要发布....
我创建了一个只接受整数作为输入的编辑框。我没有使用TMaskEDit,因为我想从中派生出一堆其他的(只接受浮点数,并且浮点数和带有最小/最大属性的整数)。
这是我的代码。我认为问题是我的属性编辑器SetValue()永远不会被调用,所以也许我没有正确注册它?
unit IntegerEditBoxMinMax;
// An edit box which only accepts integer values between the stated mix/max values
interface
uses
SysUtils, Classes, Controls, StdCtrls, DesignEditors;
type
TMinimumProperty = class(TIntegerProperty)
procedure SetValue(const newValue: string); override;
end;
TMaximumProperty = class(TIntegerProperty)
procedure SetValue(const newValue: string); override;
end;
TValueProperty = class(TIntegerProperty)
procedure SetValue(const newValue: string); override;
end;
TIntegerEditBoxMinMax = class(TCustomEdit)
private
FMinimum : Integer;
FMaximum : Integer;
FValue : Integer;
published { Published declarations - available in the Object Inspector at design-time }
property Minimum : Integer read FMinimum write FMinimum;
property Maximum : Integer read FMaximum write FMaximum;
property Value : Integer read FValue write FValue;
end; // of class TIntegerEditBoxMinMax()
procedure Register;
implementation
Uses TypInfo, Consts, DesignIntf, Dialogs;
procedure Register;
begin
RegisterComponents('Standard', [TIntegerEditBoxMinMax]);
RegisterPropertyEditor(TypeInfo(Integer), TIntegerEditBoxMinMax, 'Minumim', TMinimumProperty);
RegisterPropertyEditor(TypeInfo(Integer), TIntegerEditBoxMinMax, 'Maximum', TMaximumProperty);
RegisterPropertyEditor(TypeInfo(Integer), TIntegerEditBoxMinMax, 'Value', TValueProperty);
end;
procedure TMinimumProperty.SetValue(const newValue: string);
var L: Longint;
min, max : Integer;
propInfo: PPropInfo;
exceptionString : String;
begin
MessageDlg('editor !!', mtWarning, [mbOK], 0); // This is never seen !!
L := StrToInt(newValue); { convert string to number }
with GetTypeData(GetPropType())^ do { this uses compiler data for type Integer }
min := GetOrdProp(GetComponent(0), 'Minimum');
max := GetOrdProp(GetComponent(0), 'Maximum');
if min > max then
begin
exceptionString := 'Minimum value (%l) cannot be greater than maximum (%l)';
raise Exception.CreateResFmt(@exceptionString, [min, max]);
end;
if L < min then
begin
PropInfo := GetPropInfo();
SetOrdProp(Nil , propInfo, Int64(min));
exceptionString := 'Value (%l) less than new minimum (%l); value set to minimum';
raise Exception.CreateResFmt(@exceptionString, [L, min]);
end;
SetOrdValue(L); { if in range, go ahead and set value }
end; // of TMinimumProperty.SetValue()
procedure TMaximumProperty.SetValue(const newValue: string);
var L: Longint;
min, max : Integer;
propInfo: PPropInfo;
exceptionString : String;
begin
L := StrToInt(newValue); { convert string to number }
with GetTypeData(GetPropType())^ do { this uses compiler data for type Integer }
min := GetOrdProp(Nil, 'Minimum');
max := GetOrdProp(Nil, 'Maximum');
if max < min then
begin
exceptionString := 'Maximum value (%l) cannot be less than minimum (%l)';
raise Exception.CreateResFmt(@exceptionString, [max, min]);
end;
if L > max then
begin
PropInfo := GetPropInfo();
SetOrdProp(Nil , propInfo, Int64(max));
exceptionString := 'Value (%l) more than new maximum (%l); value set to maximum';
raise Exception.CreateResFmt(@exceptionString, [L, max]);
end;
SetOrdValue(L); { if in range, go ahead and set value }
end; // of TMaximumProperty.SetValue()
procedure TValueProperty.SetValue(const newValue: string);
var L: Longint;
min, max: Integer;
begin
L := StrToInt(newValue); { convert string to number }
// see also http://www.freepascal.org/docs-html/rtl/typinfo/getobjectprop.html
// for other useful functions
with GetTypeData(GetPropType())^ do { this uses compiler data for type Integer }
begin
min := GetOrdProp(Nil, 'Minimum');
max := GetOrdProp(Nil, 'Maximum');
// for Float, etc, see http://www.blong.com/Conferences/BorConUK98/DelphiRTTI/CB140.htm
if (L < min) or (L > max) then { make sure it's in range... }
raise Exception.CreateResFmt(@SOutOfRange, [min, max]); { ...otherwise, raise exception }
SetOrdValue(L); { if in range, go ahead and set value }
end;
end; // of TMinimumProperty.SetValue()
end.
原始问题:
This link给出了一个关于整数属性的属性编辑器的一个很好的例子。
如何更改此方法...
procedure TIntegerProperty.SetValue(const Value: string);
var
L: Longint;
begin
L := StrToInt(Value); { convert string to number }
with GetTypeData(GetPropType)^ do { this uses compiler data for type Integer }
if (L < MinValue) or (L > MaxValue) then { make sure it is in range }
{ otherwise, raise exception }
raise EPropertyError.Create(FmtLoadStr(SOutOfRange, [MinValue, MaxValue]));
SetOrdValue(L); { if in range, go ahead and set value }
end;
...我想要的是男性一个新的属性,比如TIntegerMinMaxProperty
,派生自TIntegerProperty
,其中组件编辑器也显示整数的最小和最大允许值。
我正在考虑添加两个新的Integer属性,名为Minimum&amp;最大,但看起来我可以使用现有的MinValue&amp; MaxValue如果我只能发布它们,但我不知道如何...这些都不是
published { available in the Object Inspector at design-time }
property Minimum : Longint read MinValue write MinValue;
property Minimum : Longint read FMinValue write FMinValue;
所以看起来我有两种选择并且两者都被困在了: - /
1)找到一种方法来发布那些MinValue&amp; MaxValue属性(可能更干净) 2)发布2个新房产,Minimujm&amp;最大值并计算如何在TIntegerProperty.SetValu()
中引用它们并且感激不尽,因为这是我第一次进入属性编辑器(如果它有助于影响对此的答案,我的下一个属性将是一个接受十进制输入,有一个点)
答案 0 :(得分:2)
如果MinValue和MaxValue已经是您的组件/控件的属性,但当前是公共的并且未公布,您只需要在已发布的部分中重新声明它们,但只能按名称重新声明:
published
property MinValue;
property MaxValue;
这将仅更改这些属性的可见性,并且如果支持其类型,则应使它们显示在对象检查器中。看看许多T ...与TCustom ...类对,其中T ...类通常只重新声明已发布的属性,以使它们显示在Object Inspector中。
修改(回复评论)
好的,如果你想要一些控制,请坚持下去,说一个TMyEdit说一个SomeFactor Integer属性,Object Inspector中的条目不仅会显示SomeFactor的值,还会显示允许的最小值和最大值对于SomeFactor,你需要一个代码属性编辑器来显示它自己的形式。
您当然可以将MinValue和MaxValue添加到TIntegerProperty的后代,并在GetValue和SetValue方法的覆盖中使用它们(这就是它们毕竟是虚拟的原因),然后注册此TMinMaxIntegerProperty以供SomeFactor属性使用。但是,这不会使MinValue和MaxValue显示在Object Inspector中,因为TIntegerProperty基本上只编辑/显示SomeFactor的实际值。要实现您想要的功能,您必须编写自定义属性编辑器的后代,例如显示要编辑和格式化字符串的表单的后代。我使用的组件中有很多例子,但我当然不能在这里发布他们的代码。
如果您想要的只是具有SomeFactor整数属性的TMyEdit,并且想要向您的TMyEdit控件添加SomeFactorMinValue和SomeFactorMaxValue,则可以通过FPropList条目的Instance引用访问GetValue / SetValue方法中的那些。请参阅TIntegerProperty编辑器中用于获取信息的SetOrdValue实现。它使用SetOrdProp(来自TypInfo)来设置Instance的值,该值应该是对包含SomeFactor属性的TMyEdit控件的引用。通过一些转换,您应该可以使用SomeFactorMinValue和SomeFactorMaxValue属性。
注意:不确定FPropList如何获取其条目。它通过构造函数得到了它的计数。你可能需要自己做一些进一步的调查。 (出于某种原因,Ctrl-click和代码洞察决定在我的D2009中继续罢工。)