Форум: "Начинающим";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];
ВнизTTreeView & OnChange Найти похожие ветки
← →
mfender © (2006-03-06 10:05) [0]Много искал, но что-то ничего толкового не нашёл.
Вобщем, ушнаследовал от TTreeView. С Click"ом всё получилось быстро и легко:
TmfTreeView = class(TTreeView)
protected
procedure Click; override;
end;
implementation
procedure TmfTreeView.Click;
begin
inherited Click;
Self.ChangeDataSet;
end;
Что можно сделать, чтобы унаследовать OnChange и добавить в обработчик своё? У меня не получается. Change - не виртуальный метод, а определённое событие TTVChangedEvent.
← →
Ega23 © (2006-03-06 10:26) [1]
TmfTreeView = class(TTreeView)
FTreeViewOnChange:TTVChangedEvent;
protected
constructor Create(AOwner:TComponent);
procedure TreeViewOnChange(Sender: TObject; Node: TTreeNode);
end;
constructor TmfTreeView.Create(AOwner:TComponent);
begin
FTreeViewOnChange:=Self.OnChange; // Запоминаем, определён ли базовый OnChange;
Self.OnChange:=TreeViewOnChange; // Подставляем собственный обработчик
end;
procedure TmfTreeView.TreeViewOnChange(Sender: TObject; Node: TTreeNode);
begin
if assigned(FTreeViewOnChange) then
FTreeViewOnChange(Sender, Node); // Если базовый был определён, то выполняем его.
/////// Тут уже свои навороты
end;
В целом так.
← →
Ega23 © (2006-03-06 10:27) [2]Совет: наследуйся не от TTreeView, а от TCustomTreeView.
← →
mfender © (2006-03-06 10:29) [3]Спасибо, Дружище!
← →
mfender © (2006-03-06 10:34) [4]Олег, т.е. со всеми событиями так и поступать в дальнейшем?
Кстати, а почему наследовать лутше от TCustomTreeView?
← →
Ega23 © (2006-03-06 10:58) [5]
> Кстати, а почему наследовать лутше от TCustomTreeView?
А ты загляни в исходники TTreeView. Это всего-лишь обёртка вокруг TCustomTreeView. В нём (TTReeView) никакой логики не зашито, только определены public, private и published свойства.
> Олег, т.е. со всеми событиями так и поступать в дальнейшем?
Это если оно тебе надо.
Вот пример, так сказать, "на пальцах":
Ты пишешь свой DB-компонент. По каким-то причинам решил не пользоваться той идеологией, которую Borland предлагает (TDataSet->TDataSource->TDataLink). Имеешь на это право.
Но в таком случае тебе нужно знать следующие вещи:
1. Когда набор данных изменил свойство Active (открылся - закрылся)
2. Когда в наборе данных поменялась позиция курсора.
Есть ещё, но первых двух для начала вполне достаточно.
Теоретически, всю эту информацию ты можешь вытащить, написав обработчики TDataSet.OnScroll (или AfterScroll, точно не помню) и TDataSet.OnAfterOpen.
Казалось бы - что проще: взять и в ран-тайме подменить эти обработчики своими. Но тогда, если у тебя 2 экземпляра твоего компонента, "смотрящие" на один и тот же НД - ты получишь полную ерунду, т.к. "захватит" НД последний созданный. А если кто-то ещё раньше этот обработчик определил?
Вот для этого ты и запоминаешь указатель на предыдущий обработчик, и если он не nil - вызываешь его, а потом исполняешь собственный код. В общем, некий аналог inherited.
← →
mfender © (2006-03-06 11:04) [6]
> А ты загляни в исходники TTreeView. Это всего-лишь обёртка
> вокруг TCustomTreeView. В нём (TTReeView) никакой логики
> не зашито, только определены public, private и published
> свойства.
Заглядывал. Именно с этого я и начал. Впрочем, мысль один раз была, унаследовать от TCustomTreeView.
> Казалось бы - что проще: взять и в ран-тайме подменить эти
> обработчики своими. Но тогда, если у тебя 2 экземпляра твоего
> компонента, "смотрящие" на один и тот же НД - ты получишь
> полную ерунду, т.к. "захватит" НД последний созданный. А
> если кто-то ещё раньше этот обработчик определил?
Вот потому и решился написать свой DBTreeView. Ибо изначально я понаписал прямо в основном юните столько, что сам ничего уже не понимаю по прошествии двух месяцев.)))
Ещё раз спасибо!
← →
begin...end © (2006-03-06 11:07) [7]> mfender © (06.03.06 10:05)
> Change - не виртуальный метод
Не виртуальный, но динамический. Так что проблем с перекрытием не вижу.
TMyTreeView = class(TCustomTreeView)
procedure Change(Node: TTreeNode); override;
end;
procedure TMyTreeView.Change(Node: TTreeNode);
begin
...
inherited;
...
end
← →
mfender © (2006-03-06 11:10) [8]
> Не виртуальный, но динамический. Так что проблем с перекрытием
> не вижу.
Вот именно так я и пытался, но ничего не получилось.
← →
begin...end © (2006-03-06 11:14) [9]> mfender © (06.03.06 11:10) [8]
Не понял. Как пробовали? Что ожидали? Что не получилось?
Да, в [7] Change нужно в protected разместить. Забыл...
← →
mfender © (2006-03-06 11:25) [10]
> Не понял. Как пробовали? Что ожидали? Что не получилось?
Вот так и писал:
procedure Change(Sender: TObject; Node: TTreeNode); override;
В ответ мне - ошибка, про то, что объявление метода Change не похоже на оригинальный метод.
← →
Ega23 © (2006-03-06 11:29) [11]
> Вот так и писал:
> procedure Change(Sender: TObject; Node: TTreeNode); override;
>
> В ответ мне - ошибка, про то, что объявление метода Change
> не похоже на оригинальный метод.
Конечно ругаться будет. Ибо:
procedure Change(Node: TTreeNode); dynamic;
← →
begin...end © (2006-03-06 11:29) [12]> mfender © (06.03.06 11:25) [10]
А Sender-то откуда взялся? Ещё раз: обработчик OnChange вызывается из динамического метода Change. Его можно перекрыть:
TMyTreeView = class(TCustomTreeView)
protected
procedure Change(Node: TTreeNode); override;
end
и, кроме вызова метода родителя (а значит, и вызова обработчика OnChange) делать в нём ещё что-нибудь.
← →
mfender © (2006-03-06 11:33) [13]
> Ещё раз: обработчик OnChange вызывается из динамического
> метода Change
Ок. Приму к сведению. Попробую ещё раз и так.
Спасибо.
← →
Ega23 © (2006-03-06 11:36) [14]А в native-обработчике стоит
procedure TCustomTreeView.Change(Node: TTreeNode);
begin
if Assigned(FOnChange) then FOnChange(Self, Node);
end;
Так что действительно можно переопределить Change. Только inherited не забудь поставить...
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.03.19;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.02 c