Текущий архив: 2006.10.15;
Скачать: CL | DM;
ВнизAssign для наследника TCollectionItem Найти похожие ветки
← →
Priest © (2006-02-26 16:51) [0]Создаю свою коллекцию и класс производный от TCollectionItem. Элемент коллекции содержит ссылку на TButton. Коллекцию помещаю в виде publisher свойства в компонент. Компонент кладу в базовую форму и в коллекции создаю в Дезайн-Тайм несколько элементов. Потом создаю производную форму. В производной форме появляются все мои элементы. Но ссылки на кнопки появляются в виде Имяпеременной.Имя кнопки. В момент запуска происходит ошибка. Если я ручками строки Имяпеременной.Имя кнопки меняю на Имя кнопки, то всё работает. Как правильно писать метод Assign?
← →
jack128 © (2006-02-26 17:48) [1]посмотри вот здесь http://delphimaster.net/view/5-1133168076/
кажись твоя проблема...
← →
Priest © (2006-02-27 10:13) [2]Нет. Там что то не то
← →
Юрий Зотов © (2006-02-27 12:26) [3]
unit RefToButton;
interface
uses
Classes, StdCtrls;
type
TYzItem = class(TCollectionItem)
private
FButton: TButton;
procedure SetButton(const Value: TButton);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); dynamic;
procedure AssignTo(Dest: TPersistent); override;
published
property Button: TButton read FButton write SetButton;
end;
TYzItems = class(TOwnedCollection)
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); dynamic;
end;
TYzItemsContainer = class(TComponent)
private
FItems: TYzItems;
procedure SetItems(const Value: TYzItems);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Items: TYzItems read FItems write SetItems;
end;
implementation
{ TYzItem }
procedure TYzItem.AssignTo(Dest: TPersistent);
begin
if Dest is TYzItem then
TYzItem(Dest).SetButton(FButton)
else
inherited
end;
procedure TYzItem.Notification(AComponent: TComponent; Operation: TOperation);
begin
if (Operation = opRemove) and (AComponent = FButton) then
FButton := nil
end;
procedure TYzItem.SetButton(const Value: TButton);
begin
if FButton <> Value then
begin
if FButton <> nil then
TComponent(Collection.Owner).RemoveFreeNotification(FButton);
FButton := Value;
if FButton <> nil then
TComponent(Collection.Owner).FreeNotification(FButton);
Changed(False)
end
end;
{ TYzItems }
procedure TYzItems.Notification(AComponent: TComponent; Operation: TOperation);
var
i: integer;
begin
BeginUpdate;
try
for i := 0 to Count - 1 do
TYzItem(Items[i]).Notification(AComponent, Operation)
finally
EndUpdate
end
end;
{ TYzItemsContainer }
constructor TYzItemsContainer.Create(AOwner: TComponent);
begin
inherited;
FItems := TYzItems.Create(Self, TYzItem)
end;
destructor TYzItemsContainer.Destroy;
begin
FItems.Free;
inherited
end;
procedure TYzItemsContainer.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if FItems <> nil then
FItems.Notification(AComponent, Operation)
end;
procedure TYzItemsContainer.SetItems(const Value: TYzItems);
begin
FItems.Assign(Value)
end;
end.
← →
Priest © (2006-02-27 16:19) [4]У меня точно так же реализовано. И Ващ код, так же как и мой не работает.
Я делал так. Взял Ваш код, добавил его в пакет и установил компонент в палитру. Потом в тот же пакет добавил форму и разместил на ней 2 кнопки. Создал два элемента, вот ДФМ
object Button1: TButton
Caption = "Button1"
end
object Button2: TButton
Caption = "Button2"
end
object YzItemsContainer1: TYzItemsContainer
Items = <
item
Button = Button1
end
item
Button = Button2
end>
end
Это у меня базовая форма. Я перебилдил пакет. И добавил в него производную форму. Вот что получилось в производной ДФМ.
inherited Form3: TForm3
Caption = "Form3"
OldCreateOrder = True
PixelsPerInch = 96
TextHeight = 13
inherited YzItemsContainer1: TYzItemsContainer
Items = <
item
Button = Form2.Button1
end
item
Button = Form2.Button2
end>
end
end
То есть ссылка у меня не Button = Button1, а Button = Form2.Button1. Если я убираю слово Form2, то всё работает. Но если затем добавить в класс TYzItemsContainer какой либо метод или переменную, то опять прописывается Form2.
Как быть?
← →
Юрий Зотов © (2006-02-27 20:03) [5]Вряд ли стоит хранить формы в пакете - для этого есть репозиторий. И с ним все прекрасно работает (вот чес-слово, я не выкладываю непроверенный код).
← →
Priest © (2006-02-28 09:09) [6]Да проблема в том, что я потом форму использую в Dream Designer. Поэтому загоняю их в пакет.
>>вот чес-слово, я не выкладываю непроверенный код
Я не сомневаюсь. Но проделайте описанную мной последовательность и увидите тот же результат. Причём даже если удалиль глобальную переменную Form2, Дельфи всё равно сериализует вот так: Form2.Button2.
Я пробовал редактор свойста сделать и вырезать имя формы. В инспекторе отображается нормально, но в дфм пишется всё также.
Вобщем из решения я придумал лишь следующее. Делаю publisher свойство типа string, в котором заношу имя компонента-кнопки. В момент присвоения ищу данную кнопку на текущей форме и присваиваю своему, уже public свойству Button:TButton
← →
Юрий Зотов © (2006-02-28 09:48) [7]> Priest © (28.02.06 09:09) [6]
Не только в момент присвоения, еще и в Loaded. Причем в момент присвоения так:
if not (csLoading in ComponentState) then ...
Поскольку кнопка может грузиться и после компонента - то есть, в момент присвоения ее может еще не быть.
← →
Priest © (2006-02-28 11:54) [8]Не понял. Ведь я сохраняю только ссылку на кнопку. Ну и что если она ещё не загружена. Она ведь уже создана как объект. Просто не проиниированы свойства.
← →
Юрий Зотов © (2006-02-28 12:31) [9]> Priest © (28.02.06 11:54) [8]
При загрузке формы кнопка не создана, до тех пор, пока при чтении DFM до нее не дойдет очередь. Соответственно, если Ваш компонент визуальный и загружается раньше кнопки, то в методе SetButton получить ссылку на нее он не сможет (поскольку объекта-кнопки еще нет), а в Loaded - сможет.
Если компонент невизуальный, он всегда будет загружаться позже кнопки.
← →
Priest © (2006-02-28 12:57) [10]Спасибо за терпение. учту
Страницы: 1 вся ветка
Текущий архив: 2006.10.15;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.05 c