Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.34.85] |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
На форме содержиться несколько Edit и в каждом надо проверять вводимые символы (только цифры и минус).
Проблема в том, что я не знаю как оптимизировать код (громоздким не делать). Т.е. для каждого edit нужно писать вот этот кусочег кода case key of '0'..'9': ; '-' : if length(Edit1.Text)<>0 then key:=#0; else key:=#0; end; Можно, конечно, и сделать отдельную процедуру, в которую будем передавать вводимый символ и сам editN. вот так это будет: type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; procedure k1(Sender: TObject; var Key: Char); procedure k2(Sender: TObject; var Key: Char); procedure k3(Sender: TObject; var Key: Char); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} Procedure control(var ch: char; var edt: TEdit); begin case ch of '0'..'9': ; '-' : if length(edt.Text)<>0 then ch:=#0; else ch:=#0; end; end; procedure TForm1.k1(Sender: TObject; var Key: Char); begin control(key, Edit1); end; procedure TForm1.k2(Sender: TObject; var Key: Char); begin control(key, Edit2); end; procedure TForm1.k3(Sender: TObject; var Key: Char); begin control(key, Edit3); end; end. Нельзя ли как нибудь это упростить? хм, только щас заметил, а почему все заголовки процедур состоят только из TForm1.k*? а где же ещё название edit'a? разьве не должно быть так TForm1.Edit1k1(.....var key:char);? Событие onKeyPress обрабатывается. |
Сообщ.
#2
,
|
|
|
сдедай для одного Edit а всем остальным укажи тот же метод.
Цитата Continental @ хм, только щас заметил, а почему все заголовки процедур состоят только из TForm1.k*? а где же ещё название edit'a? разьве не должно быть так TForm1.Edit1k1(.....var key:char);? методы называются TForm1.CompanentNameMethode(Sender: TObject...........) |
Сообщ.
#3
,
|
|
|
Спасибо, что помогли. Я понял, впринципе, любому обекту можно один и тот же метод назначить.
Добавлено а как же тогда проверять длинну строки в edit'e? чтобы минус написать только первым и не "пять" раз есть вот такая проверка: procedure TForm1.contr(Sender: TObject; var Key: Char); begin case key of '0'..'9', #8: ; '-' : if length(Edit1.Text)<>0 then key:=#0; <------- length else key:=#0; end; end; И если несколько edit'oв пользуются одним методом, то что надо написать в Length(?) |
Сообщ.
#4
,
|
|
|
length(TEdit(Sender).Text)
|
Сообщ.
#5
,
|
|
|
[quote=Continental,1221139547,2066876]'-' : if length(Edit1.Text)<>0 then key:=#0; <------- length[/quote]
Параметр Sender это и есть Edit, в который вводится символ '-' : if length((Sender as TEdit).Text)<>0 then key:=#0; <------- length[/quote] PS: опоздал .. |
Сообщ.
#6
,
|
|
|
Если такая задача становится достаточно часто, то можно написать свой компонент - потомок от TEdit
|
Сообщ.
#7
,
|
|
|
А почему можно написать в скобках
Цитата Shaggy @ и с помощью asTEdit(Sender).Text Цитата leo @ Т.е. это где-то играет роль в каких-либо определённых случаях, или это просто такая обширность у языка?(Sender as TEdit).Text Цитата and85 @ Если такая задача становится достаточно часто, то можно написать свой компонент - потомок от TEdit Пока что мне до этого далеко. А вот можете пожалуйста помочь ещё с одним вопросом. В моём случае есть три edit'a и кнопка вычислить (сложить всё что во всех полях), причём если хоть один edit не заполнен - кнопка Button1.Enabled:=false; Я проверял поля при помощи onChange: procedure TFm_Tover.Pr(Sender: TObject); begin if Edt_name.Text<>'' then begin if Edt_price.Text<>''then begin if Edt_count.Text<>''then Btn_Calc.Enabled:=true else Btn_Calc.Enabled:=false; end else Btn_Calc.Enabled:=false; end else Btn_Calc.Enabled:=false; end; т.е. я с помошью if .. else проверял каждое поле и устанавливал кнопке значение Enabled. Вот только при трёх полях, алгоритм уже плохо читается. Есть какой-нибудь способ, чтобы сократить данный код? Тему новую не стал создавать, так как посчитал, что речь идёт почти про одно и то же, так что не сочтите мусором. |
Сообщ.
#8
,
|
|
|
для определённости:
1) TEdit(Sender) и 2) (Sender as TEdit) 1) a) стоит исползовать только если Sender - это именно TEdit(в данном случае) т.е. фактически это инструкция компилятору - "заткнись и делай, что велено..." б) никаких проверок не производится, и если на самом деле Sender это не TEdit, то в результате получищь кучу глуков - от: странное поведение программы, до AV 2) так называемое "безопасное приведение типов", т.е. производится проверка: Sender - это на самом деле TEdit? и если нет, возбуждается исключение EInvalidCast |
Сообщ.
#9
,
|
|
|
Цитата Shaggy @ никаких проверок не производится, и если на самом деле Sender это не TEdit, то в результате получищь кучу глуков - от: странное поведение программы, до AV А я видел как Sender использовался с Button. .... procedure TForm1.DigitBtnClick(Sender: TObject); var Btn: TButton; ch: Char; begin Btn := Sender as TButton; ch := Chr(48+Btn.Tag); ..... ...... это значит относится ко второму пункту ----> Цитата Shaggy @ 2) так называемое "безопасное приведение типов", т.е. производится проверка: Sender - это на самом деле TEdit? и если нет, возбуждается исключение EInvalidCast |
Сообщ.
#10
,
|
|
|
Continental думаю помочь решить проблему может написание собственого компонента с рассшренными возможностями по контролю ввода ...
з.ы.: в архиве прилагается мое видение решения данной проблемы ... Прикреплённый файлXPEdit.rar (8.88 Кбайт, скачиваний: 394) |
Сообщ.
#11
,
|
|
|
Цитата Continental @ Есть какой-нибудь способ, чтобы сократить данный код? Btn_Calc.Enabled:=(Edt_name.Text<>'') and (Edt_price.Text<>'') and (Edt_count.Text<>''); Хотя думается в данном случае лучше не дизэйблить кнопку, а вынести проверки в обработчик нажатия Btn_CalcClick и если один из эдитов не заполнен то выдавать сообщение или бип и переводить фокус на пустой эдит procedure TForm1.Btn_CalcClick(Sender: TObject); function IsEmpty(e:TEdit;const what:string):boolean; begin Result:=e.Text = ''; if Result then begin beep; MessageDlg('Введите значение: '+what,mtWarning,[mbOk],0); FocusControl(e); end; end; begin if IsEmpty(Edt_name,'Наименование') or IsEmpty(Edt_price,'Цена') or IsEmpty(Edt_count,'Количество') then Exit; ... end; |
Сообщ.
#12
,
|
|
|
Если начать сначала.
я так и не понял, как сделать чтоб в edit`ы можно было вводить только цифры??? в каком событии писать case ch of '0'..'9': ; '-' : if length(edt.Text)<>0 then ch:=#0; else ch:=#0; ???? и сразу же второе, как сделать это сразу для нескольких edit`ов? как работать с методами TForm1.CompanentNameMethode(Sender: TObject...........) ???? заранее спасибо ........пис |
Сообщ.
#13
,
|
|
|
Нужно создать один обработчик Edit1KeyPress и назначить его нескольким эдитам. Причем если в обработчике используется обращение к св-вам эдита (например Text), то для того, чтобы этот обработчик был универсальным, нужно вместо прямых ссылок типа edt.Text использовать (Sender as TEdit).Text
procedure TForm1.Edit1KeyPress(Sender:TObject;var Key:Char); begin if not (Key in ['-','0'..'9']) or (Key = '-') and (Length((Sender as TEdit).Text) <> 0) then Key:=#0; end; |
Сообщ.
#14
,
|
|
|
Есть маленькое замечание. Нигде не обрабатывается вставка из буфера винды. Тоесть, если у меня в буфере белиберда 'алдывраывлоарыдлаорывдлаорыва', то нажав Shift+Insert, я смогу эту бяку к себе в эдит вставить:)
P.S. У andrew.virus это похоже учитывается:) |
Сообщ.
#15
,
|
|
|
Минутку, а backspace? почему не работает? можно удалять только кнопкой "delete".??
Объясните пожалуйста, как сделать, чтоб в определенное количество едитов. можно было вводить только цифры, и стирать кнопкой backspace??? |