2015-06-16 3 views
0

Я разрабатываю компонент DataAware и выполняю некоторый код после открытия базы данных.Обнаружение события компонента в Delphi

Это код, у меня есть на данный момент:

TMyDataAwareComponent = class(TDataAwareComponent) 
    private 
    { Private declarations } 
    procedure ToBeExecutedOnAfterOpen(DataSet: TDataSet); 
    protected 
    { Protected declarations } 
    public 
    { Public declarations } 
    constructor Create(AOwner: TComponent); override; 
    end; 

constructor TMyDataAwareComponent.Create(AOwner: TComponent); 
begin 
    inherited; 
    if Assigned(Self.DataSource) then 
    begin 
    Self.DataSource.DataSet.AfterOpen := ToBeExecutedOnAfterOpen; 
    end; 
end; 

procedure TMyDataAwareComponent.ToBeExecutedOnAfterOpen(DataSet: TDataSet); 
var 
    i: Integer; 
begin 
    // Do something here 
end; 

код работает правильно, но событие AfterOpen набора данных, связанного с компонентом не уволили больше. Как я могу убедиться, что событие AfterOpen запущено сначала в наборе данных, а затем в моем компоненте?

Есть ли решение, действующее для всех событий в наборах данных (BeforeOpen, AfterOpen, BeforeCancel, BeforeDelete, AfterCancel, AfterDelete, ... и т. Д.)?

+1

* Код работает правильно, но событие AfterOpen набора данных, связанного с компонентом не уволили больше. * Вы угнали его! –

+1

Написание компонентов, относящихся к данным, относится к уже завершенному разработчикам Delphi. Для редактора одного поля смотрите 'TDBEdit' и его поле' FDataLink'; для grid-подобных компонентов также смотрите поле «TDBGrid» и его поле «FDataLink». – Abelisto

+0

Вам необходимо проверить, что Self.DataSource.DataSet также назначен, fwiw. – MartynA

ответ

1

Вы можете использовать виртуальный метод перехватчик для перехвата DoAfterOpen виртуального вызова

FVirtualIncerceptor := TVirtualMethodInterceptor.Create(TDataSet); 
FVirtualIncerceptor.OnBefore := procedure(Instance: TObject; Method: TRttiMethod; 
    const Args: TArray<TValue>; out DoInvoke: Boolean; out Result: TValue) 
begin 
    if Method.Name = 'DoAfterOpen' then 
    ToBeExecutedOnAfterOpen(TDataset(Instance)); 
end; 
FVirtualIncerceptor.Proxify(Self.DataSource.DataSet); 

увидеть это подробнее http://docwiki.embarcadero.com/CodeExamples/XE8/en/TVirtualMethodInterceptor_(Delphi)

Я предполагаю, что вы можете увидеть, как расширить это для обработки других случаев также

0

Вам нужно будет сохранить старый DataSet.AfterOpen при назначении и вызвать этот метод сохранения в ToBeExecutedOnAfterOpen. Но, как сказал Абелисто в своем комментарии, это не путь. Это не пропустило бы ваше требование «быть недействительным для всех событий в наборах данных». Может быть, это поможет вам: http://delphidabbler.com/tips/194

0

Вы можете посмотреть на Ориентированное на Аспект Программирование. Как @Jasper указал ... Виртуальный метод Injection ...

DSharp приходит на ум, легко настраивая это. Посмотрите на DSharp.Aspects.Weaver. Вы можете легко связать любой метод, который опубликован или открыт.

-Rick

Смежные вопросы