Вы можете рассмотреть возможность использования объекта для управления NIL'ом события и восстановления ранее установленного обработчика события. Немного опасно предполагать, что восстанавливаемое событие просто оказывается назначенным во время разработки / которое имеет «подходящее имя» - вы всегда должны сохранять / восстанавливать назначенный в данный момент обработчик, просто чтобы быть в безопасности .
Это обеспечит еще более многократное использование утилиты, чем SetTextWithoutOnChange ():
TSuspendEvent = class
private
fObject: TObject;
fEvent: String;
fHandler: TMethod;
public
constructor Create(const aObject: TObject; aEvent: String);
destructor Destroy; override;
end;
constructor TSuspendEvent.Create(const aObject: TObject; aEvent: String);
const
NILEvent : TMethod = (Code: NIL; Data: NIL);
begin
inherited Create;
fObject := aObject;
fEvent := aEvent;
fHandler := GetMethodProp(aObject, aEvent);
SetMethodProp(aObject, aEvent, NILEvent);
end;
destructor TSuspendEvent.Destroy;
begin
SetMethodProp(fObject, fEvent, fHandler);
inherited;
end;
При использовании это будет выглядеть примерно так:
with TSuspendEvent.Create(Edit1, 'OnChange') do
try
Edit1.Text := 'Reset!';
finally
Free;
end;
Для "Не используйте ' с " толпой "- непременно объявите себе дополнительную локальную переменную и используйте ее, если она поможет вам спать спокойно ночью. :)
Или, чтобы сделать его еще более удобным для использования и исключения " с ", я бы сделал класс TSuspendEvent интерфейсным объектом и включил бы его использование в функцию, которая давала ссылка на интерфейс, к которой можно было бы разрешить «жить в области видимости», , как показано в моей реализации AutoFree (). Фактически, вы могли бы использовать AutoFree () как есть , чтобы управлять этим уже:
AutoFree(TSuspendEvent.Create(Edit1, 'OnChange'));
Edit1.Text := 'Reset!';
Для включения событий на период, выходящий за рамки одной процедуры, требуется больше управления, чем, вероятно, могут оказать какие-либо вспомогательные утилиты в общем виде, по крайней мере, не имея специальных средств для явного восстановления событий. , а не автоматически.
Если вы просто обернули TSuspendEvent в его собственную функцию выдачи интерфейса, следуя тому же шаблону, что и AutoFree (), вы можете упростить это далее до:
SuspendEvent(Edit1, 'OnChange');
Edit1.Text := 'Reset!';
В качестве заключительного замечания, я думаю, должно быть довольно легко увидеть, как это можно довольно просто расширить для поддержки приостановки нескольких событий на объекте за один вызов, если требуется, например:
SuspendEvent(Edit1, ['OnChange', 'OnEnter']);