TEdit で OnChange イベントで
内容が変更されたときの処理をしているのですが、
起動時にファイルからデータを読みこみ
Edit に初期データを入れようとすると
OnChange イベントが発生してしまいます。
ファイルからデータを読込Editにデータを入れるまで
グローバルフラグを使ってフラグを立てて、
OnChange イベントの先頭で
フラグがたっていれば抜けるという処理をするしか
方法がないのでしょうか?
現在OnChangeイベントが多数あるので簡単な
方法があれば教えてください。
こんにちは。
初期データを入れる直前にOnChangeイベントをnilにセットし、
初期化が完了したらイベントを再設定すればOnChangeイベントの内容を変更せずに済むと思います。
例えば、Edit1のOnChangeイベント対して、
Edit1OnChangeという手続きが設定されていたとして
begin
Edit1.OnChange := nil;
{初期化の処理}
Edit1.OnChange := Edit1OnChange;
end;
とすれば目的を達成できます。
複数のイベントを抑止したい場合はnilの代入とイベントの再設定の文が増えてしまいますが、
やってること自体は単純なので特に混乱しないと思いますし、
初期化を行う手続き以外には影響を与えないのがメリットだと思います。
初期化メソッド内で一度全てのEditのOnChengeを退避させれば良いので
以下ではどうでしょうか。
var
Loop, Count: Integer;
TempEvents: array of TNotifyEvent;
begin
Count := 0;
for Loop := 0 to Self.ComponentCount - 1 do
begin
if Components[Loop] is TEdit then
begin
SetLength(TempEvents, Count + 1);
TempEvents[Count] := (Components[Loop] as TEdit).OnChange;
(Components[Loop] as TEdit).OnChange := nil;
Inc(Count);
end;
end;
{ Editの変更処理 }
Count := 0;
for Loop := 0 to Self.ComponentCount - 1 do
begin
if Components[Loop] is TEdit then
begin
{ Components配列に変化がない事が前提 }
(Components[Loop] as TEdit).OnChange := TempEvents[Count];
Inc(Count);
end;
end;
TCheckBoxのCheckedの変更でOnClickが発生する等他にも初期化時に
いちいちイベントに飛ばれると面倒な場合は何らかの形でイベントの
メソッドポインタを退避させれば良いと思います。
基本的にはぼるしちさんや邪さんと方法は同じなのですが、
以下のようにしておくと若干楽かもしれません。
type
TEdit = class(StdCtrls.TEdit)
private
procedure SetInitText(const Value: string);
public
property InitText: string write SetInitText;
end;
// ↑フォームクラス宣言の上に書く
TForm1 = class(TForm)
...
procedure TEdit.SetInitText(const Value: string);
var
tmp: TNotifyEvent;
begin
tmp := Self.OnChange;
Self.OnChange := nil;
try
Self.Text := Value;
finally
Self.OnChange := tmp;
end;
end;
これでTEditにInitTextプロパティが追加されるので、
Textプロパティに代入する代わりにInitTextに代入すると
イベントを発生させずにデータを入れられると思います。
ツイート | ![]() |