Editで最大、最小などの制限を設けたもの

解決


YO  2010-02-06 01:16:21  No: 37465

Editで数値を入力したときに、最大最小を判断して、範囲内でなければ入力できない・数値が入らないなどの処理をしたいです。

現在はイベントのOnExitなどを利用してその値が範囲内にあるかどうかを判断しています。

ですが非常に一つ一つ範囲がちがいますので、結構大変です。

もともとのEditの設定にMax Minを入れる場所があってそこに入れたらその範囲いがい受け付けないようにしたいです。
そういったものありますか?
Delphiにはないのでしょうか?

何かいい方法知っている方いますでしょうか?

よろしくお願いします。


ttt  2010-02-06 01:37:04  No: 37466

お使いのバージョンにあるかどうかはわかりませんが、
例えばSamplesページのTSpinEditはどうでしょうか?
あるいは、Win32ページにあるTUpDownを貼り付けても似たようなことができます。


YO  2010-02-06 01:46:19  No: 37467

確かにSpinとかUpDownをしようすればできますよね。

やはりその二つを使用するしか方法はなさそうですかね?
またはSpinとかの矢印を消すことはできないのでしょうか?(SpinをEditに見せかける)


Kenny  2010-02-06 04:23:04  No: 37468

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があります。

インストールの仕方が分からないときは、また質問してください。


monaa  2010-02-06 04:26:37  No: 37469

Editにある機能を加えたEditを作りたいのであれば
コントロールの継承といった手段があります。
まさにオブジェクト指向の王道です、知ってて損はないと思いますよ。
DelphiはさらにGUIベースで開発できるような機能も持っていますが、この場合コンポーネントのインストールが必要になります。


Delphi大好き  2010-02-06 07:29:05  No: 37470

あまりスマートではではない方法ですが自分の思いつき・・・
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);

完全な素人流ですが書いてみました^^;


頭悪いね  2010-02-07 01:57:42  No: 37471

そんなコード書くくらいならUpdownなんて使わずにそのまま値を比較すればいいじゃん
複数のコントロールで別々の範囲を設定したいからコード書かずにプロパティ指定だけしたいってことでしょ
素人でももっとマシなアイデア思いつくよ


KHE00221  2010-02-07 06:23:11  No: 37472

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;


YO  2010-02-11 00:18:48  No: 37473

みなさん、色々回答ありがとうございます。

やはりDelphiでは簡単にできなそうですね。
「OnExitのイベントで比較してだめなら設定した値を受けつけない。」
というやりかたを一つ一つ地道にやっていくしかなさそうですね。


は?  2010-02-11 01:30:51  No: 37474

そういう処理をまとめたコンポーネントをTEdit継承して作るだけなのに
何をもって「簡単にできなそう」と判断したんですか?
上のほうでいくつもそのまま使える回答が出てるのにハナから理解する気ないでしょ

そもそもやりたいことが常に存在してるようであればプログラミングなんていりません
なければ作るというのがプログラミングというものでしょう
あなた向いてないんじゃないですか?


manbon  2010-02-11 01:50:27  No: 37475

変なコードですが、コンポーネントを作らなくても一応動作します。
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;


YO  2010-02-12 17:56:20  No: 37476

軽率な発言すいませんでした。

コンポーネントを作成したり継承したりとなにかしらやらなければいけないのですね。

TGEditを継承するか、新たにコンポーネントを作成して自分なりに比較するものを作成したいと思います。

みなさん回答ありがとうございました。


YO  2010-02-12 17:56:51  No: 37477

すいません、解決とします。

ありがとうございました。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加