Editで数値を入力したときに、最大最小を判断して、範囲内でなければ入力できない・数値が入らないなどの処理をしたいです。
現在はイベントのOnExitなどを利用してその値が範囲内にあるかどうかを判断しています。
ですが非常に一つ一つ範囲がちがいますので、結構大変です。
もともとのEditの設定にMax Minを入れる場所があってそこに入れたらその範囲いがい受け付けないようにしたいです。
そういったものありますか?
Delphiにはないのでしょうか?
何かいい方法知っている方いますでしょうか?
よろしくお願いします。
お使いのバージョンにあるかどうかはわかりませんが、
例えばSamplesページのTSpinEditはどうでしょうか?
あるいは、Win32ページにあるTUpDownを貼り付けても似たようなことができます。
確かにSpinとかUpDownをしようすればできますよね。
やはりその二つを使用するしか方法はなさそうですかね?
またはSpinとかの矢印を消すことはできないのでしょうか?(SpinをEditに見せかける)
TEditを拡張したコンポを作ってみました。ほぼSampleのSpinEditの移植です。
一応ちゃんと動くようですが、コンポ作りは(も)素人なので、どなたか突っ込みを入れてください。
あくまでこんな事もできるよ、ということで。
ここから
unit EditLimited;
interface
uses
SysUtils, Classes, Controls, StdCtrls, Messages, Windows ;
type
TEditLimited = class(TEdit)
private
FMinValue: LongInt;
FMaxValue: LongInt;
FEditorEnabled: Boolean;
function CheckValue (NewValue: LongInt): LongInt;
function GetValue: LongInt;
procedure SetValue (NewValue: LongInt);
protected
function IsValidChar(Key: Char): Boolean; virtual;
procedure KeyPress(var Key: Char); override;
procedure Change; override;
public
constructor Create(AOwner: TComponent); override;
published
property MaxValue: LongInt read FMaxValue write FMaxValue;
property MinValue: LongInt read FMinValue write FMinValue;
property Value: LongInt read GetValue write SetValue;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Sample', [TEditLimited]);
end;
constructor TEditLimited.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Text := '0';
FEditorEnabled := True;
end;
function TEditLimited.GetValue: LongInt;
begin
try
Result := StrToIntDef(Text, 0);
except
Result := FMinValue;
end;
end;
procedure TEditLimited.SetValue (NewValue: LongInt);
begin
Text := IntToStr (CheckValue (NewValue));
end;
function TEditLimited.CheckValue (NewValue: LongInt): LongInt;
begin
Result := NewValue;
if (FMaxValue <> FMinValue) then begin
if NewValue < FMinValue then
Result := FMinValue
else if NewValue > FMaxValue then
Result := FMaxValue;
end;
end;
procedure TEditLimited.KeyPress(var Key: Char);
begin
if not IsValidChar(Key) then begin
Key := #0;
end;
if Key <> #0 then begin
inherited KeyPress(Key);
end
end;
procedure TEditLimited.Change;
begin
if CheckValue (Value) <> Value then SetValue (Value);
end;
function TEditLimited.IsValidChar(Key: Char): Boolean;
begin
Result := (Key in [DecimalSeparator, '+', '-', '0'..'9']) or
((Key < #32) and (Key <> Chr(VK_RETURN)));
if not FEditorEnabled and Result and ((Key >= #32) or
(Key = Char(VK_BACK)) or (Key = Char(VK_DELETE))) then
Result := False;
end;
end.
ここまでをEditLimited.pasというファイル名で保存して、コンポーネント-インストールしてください。
使い方は普通のEditと同じで、SpinEditのようにMaxValue、MinValueがあります。
インストールの仕方が分からないときは、また質問してください。
Editにある機能を加えたEditを作りたいのであれば
コントロールの継承といった手段があります。
まさにオブジェクト指向の王道です、知ってて損はないと思いますよ。
DelphiはさらにGUIベースで開発できるような機能も持っていますが、この場合コンポーネントのインストールが必要になります。
あまりスマートではではない方法ですが自分の思いつき・・・
updownを配置してeditに連結して範囲を指定
visbleをfalseにして見えないように・・・
で、editのonchingにに以下を書き込み
if edit1.Text > inttostr(UpDown1.Max) then
edit1.Text := inttostr(UpDown1.max);
if edit1.Text < inttostr(UpDown1.Min) then
edit1.Text := inttostr(UpDown1.Min);
完全な素人流ですが書いてみました^^;
そんなコード書くくらいならUpdownなんて使わずにそのまま値を比較すればいいじゃん
複数のコントロールで別々の範囲を設定したいからコード書かずにプロパティ指定だけしたいってことでしょ
素人でももっとマシなアイデア思いつくよ
OnChangeは入力の度に飛んでくるので
ここで範囲を判断すると Min 10 Max 60 とかの場合入力できなくなるよ?
数値入力にしたければ
procedure TEdit.CreateParams(var params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or ES_RIGHT or ES_NUMBER;
end;
みなさん、色々回答ありがとうございます。
やはりDelphiでは簡単にできなそうですね。
「OnExitのイベントで比較してだめなら設定した値を受けつけない。」
というやりかたを一つ一つ地道にやっていくしかなさそうですね。
そういう処理をまとめたコンポーネントをTEdit継承して作るだけなのに
何をもって「簡単にできなそう」と判断したんですか?
上のほうでいくつもそのまま使える回答が出てるのにハナから理解する気ないでしょ
そもそもやりたいことが常に存在してるようであればプログラミングなんていりません
なければ作るというのがプログラミングというものでしょう
あなた向いてないんじゃないですか?
変なコードですが、コンポーネントを作らなくても一応動作します。
Edit2のOnKeyUpはEdit1のものを割り当てます。
あんまりお勧めはできませんが・・・
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
bo: Boolean;
ls: Single;
begin
if TEdit(Sender).Text <> '' then begin
try
ls := StrToFloat(TEdit(Sender).Text);
bo := ((ls >= TEdit(Sender).Tag) and (ls <= TEdit(Sender).HelpContext));
except
bo := False;
end;
if bo then TEdit(Sender).Hint := TEdit(Sender).Text
else TEdit(Sender).Text := TEdit(Sender).Hint;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Tag := 0; //最小値
Edit1.HelpContext := 100; //最大値
Edit2.Tag := 0;
Edit2.HelpContext := 200;
Edit1.Text := '0';
Edit2.Text := '0';
end;
軽率な発言すいませんでした。
コンポーネントを作成したり継承したりとなにかしらやらなければいけないのですね。
TGEditを継承するか、新たにコンポーネントを作成して自分なりに比較するものを作成したいと思います。
みなさん回答ありがとうございました。
すいません、解決とします。
ありがとうございました。
ツイート | ![]() |