Borland明显对TCollection的操作粗制滥造!一、在Object TreeView右键点击TCollection对象,Add Item。受不了他们,他们用的是内部的保护方法既不是InsertItem也不是外部的Add方法。捕获不到Add的信息。而用TCollection的属性编辑器是毫无问题的。二、TCollection的属性编辑器的删除,根本没有用Delete方法,他仅仅是把Item给Free掉就完事!TCollection里面的FItems根本没有同步删除不说!根本就没有调用Delete方法。而在Object TreeView右键点击TCollection对象,Edit -> Delete,他们用的也是私有方法RemoveItem。最抓狂的还是我这几天写的连动代码,被我删除全部重写了好几遍。我以为是我的问题,当我用CodeSite跟踪了许多地方,我才发现,是delphi的问题。唉…… 我还是自己写组件编辑器吧。如果大家使用TCollection写组件,最好还是自己写属性编辑器。唉……
二,仅把ITEM FREE掉的做法是正确的。当调用ITEM FREE后。------------------------------------------
destructor TCollectionItem.Destroy;
begin
SetCollection(nil);//把ITEM自已从LIST中删掉。
inherited Destroy;
end;
---------------------------------------------
procedure TCollectionItem.SetCollection(Value: TCollection);
begin
if FCollection <> Value then
begin
if FCollection <> nil then FCollection.RemoveItem(Self);
if Value <> nil then Value.InsertItem(Self);
end;
end;
感觉好像是想实现容器类,但是Pascal又没有泛型,所以就很别扭
begin
SelectItems([TCollection(Item).Add]);
end;就是执行了Add方法,跟踪一下:function TCollection.Add: TCollectionItem;
begin
Result := FItemClass.Create(Self);
Added(Result);
end;我想哈欠老兄所说的,自己删除自己,难道不添加自己?唉…… 就在上一行:constructor TCollectionItem.Create(Collection: TCollection);
begin
SetCollection(Collection);
end;procedure TCollectionItem.SetCollection(Value: TCollection);
begin
if FCollection <> Value then
begin
if FCollection <> nil then FCollection.RemoveItem(Self);
if Value <> nil then Value.InsertItem(Self);
end;
end;经过InsertItem,我自然得到cnAdded。但是我没有得到,而是直接得到了一个Item,而且Update方法被执行。我跳出去之后,发现才捕获了cnAdded。我奇怪的是,哪个地方执行了Update呢?Add一定被执行过了,而且是在InsertItem之前。分析InsertItem的代码,procedure TCollection.InsertItem(Item: TCollectionItem);
begin
if not (Item is FItemClass) then TList.Error(@SInvalidProperty, 0);
FItems.Add(Item);
Item.FCollection := Self;
Item.FID := FNextID;
Inc(FNextID);
SetItemName(Item);
Notify(Item, cnAdded);
Changed;
NotifyDesigner(Self, Item, opInsert);
end;只有SetItemName才有可能调用Update,跟踪之后果然是我用他调用了Update。欣喜中,自己没有真正了解机理,欣喜TCollection其实没有问题。哈。可以继续写组件了。多谢哈欠老兄点拨。