I am using Delphi 10.2, but the following may apply to other Delphi editions as well. I am developing for Android, but I am debugging the Windows release as well.
TNumberBox has property ValueType and one can set it to Integer
. The resulting behavior is inconsistent. From the one side the user can enter the number with decimal digits (e.g. 5.5
) and the TNumberBox takes care of it and it returns rounded value from its Value
property. So, the ValueType=Integer
works in some manner. On the other hand, why TNumberBox displays the Keypad with decimal points (and one can not trim this with KeypadType
property down to the integer digits only) and allows to enter decimal point/separator at all in the TNumberBox with ValueType=Integer
? So, this is sad thing about Delphi.
I have tried to make workaround with the following code, that filters out decimal separators and other non-digit characters, that execute on TNumberBox.OnTyping event:
function ReadDigits(AValue: string): string;
var i, Len, iHigh, iLow: Integer;
c: Char;
function CharIsDigit(AChar: Char): Boolean;
begin
Result:=False;
if (AChar in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) then begin
Result:=True;
end;
end;
begin
Result:='';
{iHigh:=High(AValue);
iLow:=Low(AValue);
for i:=iHigh downto iLow do begin
if (AValue[i] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) then begin
Result:=AValue[i]+Result;
end;
end;}
{//New Delphi uses 0-based strings
//https://stackoverflow.com/questions/19488010/how-to-work-with-0-based-strings-in-a-backwards-compatible-way-since-delphi-xe5
Len:=Length(AValue);
for i:=Len-1 downto 0 do begin
if (AValue[i] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) then begin
Result:=AValue[i]+Result;
end;
end; }
//It appears, that question about base is more complex and the answer may depend on the compiler directive
//https://stackoverflow.com/questions/21852034/delphi-loop-through-the-string
//It is not immediately clear, whether string-base differs among Windows/Android versions
for c in AValue do begin
if CharIsDigit(c) then
Result:=Result+c;
end;
end;
procedure TTabbedwithNavigationForm.edIntegerHoursTyping(Sender: TObject);
begin
edIntegerHours.Text:=ReadDigits(edIntegerHours.Text);
end;
But the resulting behavior is very strange in at least 2 ways:
- While
88
ir converted correctly to88
, the888
is converted to100
! QUESTION UPDATED This point is solved - TNumberBox hasMax=100
by default and this was just the effect of the default value. - One can try to click in the TNumberBox and select (highlight/mark) the number (or part of it) with the mouse and even such selection changes the number, obviously, the selection operation triggers OnTyping event etc.
There can be lot of debugging further, but I decided to stop for a moment and consult with other. Am I taking the right path to configure TNumberBox for entering integer values only? And how to do this?
ADDITIONAL UPDATE My use case requires that only positive integer values are allowed. I updated question title and added this note for clarification.