如何在运行时设计器中隐藏继承的已发布属性?

6
我正在使用一个属性检查器(例如JVCL库中的好用JvInspector),它可以很好地让我查看和编辑我的类'TMyClass'的已发布属性。 TMyClassTFrame派生,并具有一些已发布属性,这些属性是我唯一需要查看和编辑的属性。当然,TFrame有很多VCL属性,全部都是已发布的,我也可以看到。如何抑制祖先属性RTTI并仅保留自己的已发布属性?我正在使用XE3,所以世界是我的...也许。

1
Brian,如果你将你的问题标记为“Delphi”,你会获得更多的浏览量和更多获得答案的机会。 - kludg
@Serg - 谢谢。我确实想知道标记系统是如何工作的,我希望连接符“-”会生成两个标签,但这是有用的信息。 - Brian Frost
据我所知,你不能这样做。当基类被多态使用时,它会破坏代码。 - Andreas
1
可能更容易创建一个自定义的 TJvInspector 变体,根据您的要求忽略属性。 - Cosmin Prund
这就是为什么我不喜欢 TFrame :-) 在 D5 时代,我经常使用 Borland Moscow 的 Custom Containers Pack。最近听说有人将 Custom Containers Pack 移植到 XE2,或许你可以在 XE3 上运行它。试试看吧。 - Arioch 'The
3个回答

8
TCustomFrame派生您的类,并仅发布您需要的属性。虽然您基本上无法隐藏已发布的属性,但有很多受保护的属性将通过使用TCustomFrame类作为自己类的祖先而保持隐藏。
这就是VCL中几乎每个控件在类层次结构中的组成方式。例如,TLabelTCustomLabel的后代,其在类链中的唯一角色是发布您可以在对象检查器中看到的属性。

在发布问题之前,我尝试过这个方法,但令人沮丧的是,它会破坏DFM加载机制(例如“属性Align丢失”等)。因此,不幸的是,我需要基本组件行为。 - Brian Frost
2
这个方法之所以可行,是因为类中有一个 TCustom 版本。然而,在一般情况下,没有办法隐藏已经发布的属性。Brian,你可以通过编辑 DFM 文件并删除不再发布的属性来修复 DFM 加载问题。(如果你仍然需要使用这些属性,则不能在 DFM 中设置它们,因为它们不再被发布。相反,在运行时在代码中设置它们。) - Rob Kennedy
2
@Brian,你所提到的TJvInspector开源的;如果你对对象检视器的概念感到满意,那么子类化该检视器并隐藏特定属性应该不难。 - Cosmin Prund
@Brian,虽然基本上无法隐藏已发布的属性,但至少可以不公开TFrame类本身发布的属性。使用TCustomFrame将保持许多属性隐藏,因为祖先类中只有很少的属性被发布。 - TLama
1
@NGLN,嗯,那么这个答案应该被舍弃了。我应该在此之前尝试一下。感谢提醒!@Brian,请取消接受此答案,好吗?我会删除它的,因为如果您从TCustomFrame派生您的框架,那么IDE将阻止您使用它。谢谢!这些天我有一段相当(不)成功的声誉期。 - TLama
显示剩余3条评论

4

顺便说一句,我已经找到了一个关于RTTI的解决方案 - 允许仅显示当前类中你自己添加、发布的那些属性(而非祖先类或其它类的属性)。JvInspector有一个名为BeforeItemCreate的事件,其中包含将出现在检查器中的属性名称。该解决方案会检测属性名称是否属于祖先类的成员,仅当不属于时才会在检查器中显示它。好处是无需对任何检查器代码进行更改。

uses
  TypInfo;

procedure TForm1.JvInspectorBeforeItemCreate(Sender: TObject; 
  Data: TJvCustomInspectorData; var ItemClass: TJvInspectorItemClass);
begin
  if IsPublishedProp(TFrame, Data.Name) then
    ItemClass := nil;
end;

3
因为你只需要处理已发布的属性,所以不必走Delphi-2010-RTTI的路线:只需包含TypInfo并使用这个一行代码:IsPublishedProperty(TFrame, Prop.Name);更易读且无错误。(你的代码没有调用ctx.Free,这是一个bug)。 - Cosmin Prund
只有当问题被编辑为“就JvInspector而言隐藏”时,@NGLN的解决方案(虽然对于OP来说完美无缺)实际上并没有隐藏已发布的属性。它只是告诉JvInspector不要显示它们。 - Cosmin Prund
@Cos 好的,这对我来说已经足够隐藏了...;-) 我已经通过添加_在运行时设计器中_来编辑问题标题。但决定权在Brian手中。(顺便赞了TLama的答案。) - NGLN

3

在运行时创建您的TMyClass组件/框架。


但是为了保持在设计时编辑属性的能力,请不要从TFrame派生您的TMyClass。而应该从以下派生:

  • 如果需要边框,请从TCustomPanel派生
  • 如果能够自己绘制边框,请从TCustomControl派生
  • 如果可以不用边框,请从TWinControl派生

当然,您的TMyClass组件将不再出现在插入帧对话框中,而只是像其他任何组件一样。


那将是最合适的解决方案![+1] - TLama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接