Я уже как-то жаловался на тяжёлую жизнь с TNumberBox. Три основные проблемы это:
1.Значение Value и OnChange живут отдельно от происходящего в поле ввода.
2.При тыкании пальцем в контрол число может внезапно поменяться.
3.При вводе цифр в нулевое поле ноль так и остаётся в начале числа.
Но что делать? Отказаться от имеющегося, написать и регистрировать свой компонент? Я настолько глуп и ленив, что мне это всё трудно, и нужно что-то совершенно простое. Например:
Это такая подмена-заглушка, которая не требует никаких настроек среды разработки и никак не мешает в дизайн-тайме, а действует автоматически во время выполнения. DoChangeTracking выполняет обрезку лидирующего нуля (достаточно хорошо для меня) и проверяет изменения в Value. MouseMove перекрывает обработку скрола ( всего-то навсего можно было сохранять значение ноль в вертикальной прокрутке, но я глуп, и не знаю как это делать ) и на всякий случай (на всякий случай, да) вызывает "дедушкин" метод-обработчик. Вот и всё.
Теперь вставляем в интерфейсный uses наш перехватчик, чтобы он сидел в конце и переопределял тип TNumberBox.
1.Значение Value и OnChange живут отдельно от происходящего в поле ввода.
2.При тыкании пальцем в контрол число может внезапно поменяться.
3.При вводе цифр в нулевое поле ноль так и остаётся в начале числа.
Но что делать? Отказаться от имеющегося, написать и регистрировать свой компонент? Я настолько глуп и ленив, что мне это всё трудно, и нужно что-то совершенно простое. Например:
unit MyNumberBox; interface uses System.Classes, FMX.Edit; type TNumberBox = class( FMX.Edit.TNumberBox ) procedure MouseMove(Shift: TShiftState; X, Y: Single); override; procedure DoChangeTracking; override; end; implementation uses System.SysUtils, System.Character; { TNumberBox } procedure TNumberBox.DoChangeTracking; var S : String; I : Integer; V : Single; begin S := Text; if not S.IsEmpty then begin I := Low( S ); while ( S[ I ] = '0' ) and S[ I + 1 ].IsDigit do Inc( I ); if I <> Low( S ) then Text := S.Substring( I - Low( S ) ); end; if TryTextToValue( Text, V, Value ) then if not SameStr( FloatToStr( V ), FloatToStr( Value ) ) then Value := V; inherited; end; procedure TNumberBox.MouseMove(Shift: TShiftState; X, Y: Single); type PClass = ^TClass; var ClassOld: TClass; begin ClassOld := PClass(Self)^; PClass(Self)^ := TCustomEditBox; try MouseMove( Shift, X, Y ); finally PClass(Self)^ := ClassOld; end; end; end.
Это такая подмена-заглушка, которая не требует никаких настроек среды разработки и никак не мешает в дизайн-тайме, а действует автоматически во время выполнения. DoChangeTracking выполняет обрезку лидирующего нуля (достаточно хорошо для меня) и проверяет изменения в Value. MouseMove перекрывает обработку скрола ( всего-то навсего можно было сохранять значение ноль в вертикальной прокрутке, но я глуп, и не знаю как это делать ) и на всякий случай (на всякий случай, да) вызывает "дедушкин" метод-обработчик. Вот и всё.
Теперь вставляем в интерфейсный uses наш перехватчик, чтобы он сидел в конце и переопределял тип TNumberBox.
unit uMain; interface uses ... FMX.ListBox, FMX.StdCtrls, FMX.Layouts, FMX.Edit, System.Actions, FMX.ActnList, MyNumberBox; type TForm2 = class(TForm) ... ItemDenominator: TNumberBox; ...
Я использую XE5 и у меня всё работает замечательно. А как обстоят дела у вас?
Комментариев нет:
Отправить комментарий