Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.138.33.87] |
|
Сообщ.
#1
,
|
|
|
Добрый день.
Подскажите, можно ли реализовать реакцию своего компонента на события других компонентов. Идея такова: в DataSet происходит событие AfterScroll а мой компонент подменяет назначеный обработчик своим, который в свою очередь вызывает назначеный. При создании компонента динамически все отработало как нужно, но при размещении его в Дизайн тайме, обработчик не заменяется, потому что мой компонент создается раньше ДатаСета. Отсюда возникает вопрос, как реализовать "отложеное" присваивание свойств? Или есть другие методы? |
Сообщ.
#2
,
|
|
|
Вообще можно решить вопрос каковым его ставишь:
Цитата TCrash @ Подскажите, можно ли реализовать реакцию своего компонента на события других компонентов. Идея такова: в DataSet происходит событие AfterScroll а мой компонент подменяет назначеный обработчик своим, который в свою очередь вызывает назначеный. Но поясни то, откуда он у тебя возник: Цитата TCrash @ При создании компонента динамически все отработало как нужно, но при размещении его в Дизайн тайме, обработчик не заменяется, потому что мой компонент создается раньше ДатаСета. Так как это не понятно, возможно дело в ерунде. |
Сообщ.
#3
,
|
|
|
У моего компонента есть свойство DataSet. Если я создаю компонент динамически, и соответственно цепляю к нему датасет тоже динамически (после того как датасет создан и его обработчики прописаны), то все работает как надо. Т.Е. Обработчик подменяется моим, выполняется обработчик, который был ранее прописан и т.д.
Если я в дизайнтайме кладу компонент на форму и привязываю к нему лежащий там же датасет, то при запуске программы ничего не работает. В отладке выяснено, что мой компонент подменяет обраоботчик датасета, но потом, очевидно, датасету назначается обработчик, прописаный в дизайн тайме. Морочить голову с очередностью создания объектов (IMHO) не правильно. Есть ли готовые методы (алгоритмы) для подобной подмены обработчиков? |
Сообщ.
#4
,
|
|
|
А зачем всё так усложнят, а не писать код прямо в обработчике датасета?
Добавлено Да и конечного пользователя запутывать. Вот например создаст обработчик события датасета а его перекроет твой и получится кака. Или может я ошибаюсь? |
Сообщ.
#5
,
|
|
|
код моего обработчика
// my code if assigned(OldDSetAfterScroll) then OldDSetAfterScroll(DataSet); А прописывать вызов методов компонента в событии датасета.... тогда зачем компонент? |
Сообщ.
#6
,
|
|
|
TCrash, кажись ты чего-то намудрил в своем компоненте.
У меня вроде все работает, по крайней мере не смог добиться чтобы не работало Для теста создал вот такую заготовку компонента насколько смог тебя понять: unit UCatcher; interface uses Classes, DB; type TDataSetEventsCatcher = class(TComponent) strict private FDataSet: TDataSet; FOldAfterScroll: TDataSetNotifyEvent; FOwnAfterScroll: TDataSetNotifyEvent; strict protected procedure SetDataSet(DataSet: TDataSet); procedure SetAfterScroll(AfterScroll: TDataSetNotifyEvent); procedure CatchAfterScroll(DataSet: TDataSet); published property DataSet: TDataSet read FDataSet write SetDataSet; property AfterScroll: TDataSetNotifyEvent read FOwnAfterScroll write SetAfterScroll; end; procedure Register(); implementation procedure Register(); begin RegisterComponents('Doubtful Components', [TDataSetEventsCatcher]); end; { TDataSetEventsCatcher } procedure TDataSetEventsCatcher.SetDataSet(DataSet: TDataSet); begin if (FDataSet <> DataSet) then begin if (FDataSet <> nil) then FDataSet.AfterScroll := FOldAfterScroll; FDataSet := DataSet; FOldAfterScroll := nil; if ((DataSet <> nil) and (not (csDesigning in DataSet.ComponentState))) then begin FOldAfterScroll := DataSet.AfterScroll; if (@FOwnAfterScroll <> nil) then begin if (@DataSet.AfterScroll = nil) then DataSet.AfterScroll := FOwnAfterScroll else DataSet.AfterScroll := CatchAfterScroll; end; end; end; end; procedure TDataSetEventsCatcher.SetAfterScroll(AfterScroll: TDataSetNotifyEvent); begin FOwnAfterScroll := AfterScroll; if ((DataSet <> nil) and (not (csDesigning in DataSet.ComponentState))) then begin if (@FOwnAfterScroll <> nil) then begin if (@DataSet.AfterScroll = nil) then FDataSet.AfterScroll := FOwnAfterScroll else FDataSet.AfterScroll := CatchAfterScroll; end else FDataSet.AfterScroll := FOldAfterScroll; end; end; procedure TDataSetEventsCatcher.CatchAfterScroll(DataSet: TDataSet); begin if (@FOwnAfterScroll <> nil) then FOwnAfterScroll(DataSet); if (@FOldAfterScroll <> nil) then FOldAfterScroll(DataSet); end; end. Проверял так: procedure TForm1.ADODataSet1AfterScroll(DataSet: TDataSet); begin ShowMessage('Я обработчик, назначенный ДатаСету в инспекторе объектов!'); end; procedure TForm1.DataSetEventsCatcher1AfterScroll(DataSet: TDataSet); begin ShowMessage('Я обработчик, назначенный ЛовцуСобытий!'); end; Ну а по честному VahaC прав. Решение так себе. Потому как против динамического переприсваивания AfterScroll'a ДатаСету оно бессильно. И однажды даже ты сам можешь наступить на эти грабли. Я уж не говорю о том, что такой компонент нельзя распространять среди других разработчиков, собственно по озвученной причине - чтобы не подставить их под битье головой об стену в непонятках "а что же тут не работает-то?... " Да и вообще не понятно, зачем потребовалось хранить по сути две части одного и того же кода в разных местах (обработчиках)? Есть другие способы добиться твой цели, но те что я знаю тоже за гранью стандартности и универсальности. Компонент, на основе любого из них, я бы использовать не стал. |
Сообщ.
#7
,
|
|
|
Цитата arj99 @ Отсюда возникает вопрос, как реализовать "отложеное" присваивание свойств? Перекрыть метод Loaded |