面对TCollection,我…… 我快抓狂了。记于此,大家引以为戒。

leeon868 2004-09-20 08:01:14
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写组件,最好还是自己写属性编辑器。

唉……
...全文
243 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
leeon868 2004-09-22
  • 打赏
  • 举报
回复
解决了,可以结帖了。
reallike 2004-09-22
  • 打赏
  • 举报
回复
嘿嘿,谜一样的东西,终于揭开了。哈,郁闷了两个星期呢。

娃哈哈,爽!
reallike 2004-09-22
  • 打赏
  • 举报
回复
有关第一个,我找到了操作的代码:

procedure TCollectionSprig.AddType(Index: Integer);
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其实没有问题。哈。可以继续写组件了。

多谢哈欠老兄点拨。
reallike 2004-09-22
  • 打赏
  • 举报
回复
哦,我没有注意这一点,谢谢哈欠老兄提醒,原来Item是从Collection自己消灭自己。这样做甚好,在析构自己之前,从Owner那里搞掉自己。

晓得了,但是Add这个,我在看Sprig的东西,

证明我自己使用方面是错的。唉,我很希望我分析的是错的……
asj 2004-09-22
  • 打赏
  • 举报
回复
呵呵,没有好好用过TColection这个东西,当初看了看觉得有点乱
感觉好像是想实现容器类,但是Pascal又没有泛型,所以就很别扭
halfdream 2004-09-22
  • 打赏
  • 举报
回复
一,不清楚。
二,仅把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;

halfdream 2004-09-21
  • 打赏
  • 举报
回复
关注。
lw549 2004-09-21
  • 打赏
  • 举报
回复
呵呵,今天早上刚升
leeon868 2004-09-21
  • 打赏
  • 举报
回复
哦?549升星星了?
lw549 2004-09-21
  • 打赏
  • 举报
回复
up
ghchen 2004-09-21
  • 打赏
  • 举报
回复
强烈支持 + 虚心学习
李洪喜 2004-09-21
  • 打赏
  • 举报
回复
努力ing.
石头小站 2004-09-21
  • 打赏
  • 举报
回复
谢谢!为了好的组件,我们共同努力!
yalaso 2004-09-21
  • 打赏
  • 举报
回复
强烈支持 + 虚心学习
wychero 2004-09-21
  • 打赏
  • 举报
回复
大家引以为戒。顶一下。
yifan1008 2004-09-21
  • 打赏
  • 举报
回复
up
juliens 2004-09-21
  • 打赏
  • 举报
回复
警戒一下,支持一下!
leeon868 2004-09-21
  • 打赏
  • 举报
回复
好像TCollection内部根本不关心FItems这个TList对象的操作。为啥?
yijinhui2003 2004-09-20
  • 打赏
  • 举报
回复
支持一下!
leeon868 2004-09-20
  • 打赏
  • 举报
回复
哇靠!还好牛?牛什么?这里会写组件的几乎都会写组件编辑器。本来就是基础……

唉,Vcl用到TCollection的地方,无一例外的一般都不需要属性编辑器直接添加删除。

以后得注意小心使用了……

使用类似TDBGridColumns添加TColumn一定小心了…… 唉……

加载更多回复(2)

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧