Компонент-наследник. Как правильно подменить событие.

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Компонент-наследник. Как правильно подменить событие.

Сообщение wofs » 19.05.2018 11:17:40

Доброго дня.
Унаследовался от TTreeView, описал нужные мне функции. Но возник вопрос.
У TTreeView есть событие OnSelectionCanged. Я его использую в своем компоненте-наследнике, что делает невозможным корректное использование его в дальнейшем. То есть при использовании этого события в программе событие в компоненте-наследнике не работает, что нарушает логику работы наследника.

Как правильно выйти из данной ситуации?
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Компонент-наследник. Как правильно подменить событие.

Сообщение Снег Север » 19.05.2018 12:03:22

Извините, непонятно ничего. У вашего наследника свой экземпляр, у которого свой конкретный OnSelectionCanged. Каким образом какое использование OnSelectionCanged у других экземпляров класса в другом месте может на него повлиять?
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2993
Зарегистрирован: 27.11.2007 16:14:47

Re: Компонент-наследник. Как правильно подменить событие.

Сообщение wofs » 19.05.2018 12:31:25

Снег Север писал(а):Извините, непонятно ничего.

Создаю компонент-наследник
Код: Выделить всё
TwfTreeView = class(TTreeView)

В конструкторе
Код: Выделить всё
constructor TwfTreeView.Create(AnOwner: TComponent);

Использую событие для своих нужд
Код: Выделить всё
OnSelectionChanged:= @wfOnSelectionChanged;


Код: Выделить всё
procedure TwfTreeView.wfOnSelectionChanged(Sender: TObject);
begin
   fCurrentId:= GetCurrentId;
   fParentId:= GetParrentId;
end;     


Если я в коде программы, создав экземпляр своего компонента:
Код: Выделить всё
wfTreeView1: TwfTreeView;

использую событие
Код: Выделить всё
wfTreeView1.OnSelectionChanged:=@fOnSelectionChanged;

то конструкция, располагающаяся в коде моего наследника
Код: Выделить всё
procedure TwfTreeView.wfOnSelectionChanged(Sender: TObject);
begin
   fCurrentId:= GetCurrentId;
   fParentId:= GetParrentId;
end;     

ожидаемо перестает работать.
Как сделать так, что бы событие не перекрывалось?
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Компонент-наследник. Как правильно подменить событие.

Сообщение olegy123 » 19.05.2018 12:44:19

есть два пути
1) не совсем неправильный
в потомке указать на внутреннюю функцию-обработчик callback вызова.
Код: Выделить всё
OnSelectionChanged:= @wfOnSelectionChanged;
..
procedure TwfTreeView.wfOnSelectionChanged(Sender: TObject);


- тогда OnSelectionChanged будет занята, и если другой решит предопределить OnSelectionChanged тогда внутренний код перестанет работать.

2) выяснить кто вызывает OnSelectionChanged
Код: Выделить всё
  TCustomTreeView = class(TCustomControl)
..
procedure DoSelectionChanged; virtual;
..
  if Assigned(OnSelectionChanged) then OnSelectionChanged(Self);
..

DoSelectionChanged - вызывается внутри, имеет virtual, можно перекрыть своим DoSelectionChanged.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Компонент-наследник. Как правильно подменить событие.

Сообщение Vadim » 19.05.2018 13:21:50

wofs
А зачем прямо в классе присутствует присвоение событию OnSelectionChanged? Уберите его и делайте присвоение только в экземпляре класса. И всё будет тип-топ.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Компонент-наследник. Как правильно подменить событие.

Сообщение Снег Север » 19.05.2018 20:57:31

Vadim писал(а):А зачем прямо в классе присутствует присвоение событию OnSelectionChanged? Уберите его и делайте присвоение только в экземпляре класса. И всё будет тип-топ.
Да, конечно, так и надо.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2993
Зарегистрирован: 27.11.2007 16:14:47

Re: Компонент-наследник. Как правильно подменить событие.

Сообщение Ichthyander » 19.05.2018 21:20:31

Кажется единственно правильное и самое простое здесь это то что описал olegy123 во втором пункте. Практически для всех событий OnSomeMethod есть процедура DoSomeMethod, которую можно и нужно override'ить для этих целей
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 668
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Компонент-наследник. Как правильно подменить событие.

Сообщение wofs » 19.05.2018 22:40:19

olegy123 писал(а):2) выяснить кто вызывает OnSelectionChanged

Спасибо! То, что надо!
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot], Majestic-12 [Bot] и гости: 31

Рейтинг@Mail.ru