Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何阻止访问TCustomListView中的Items属性?_Delphi_Delphi Xe - Fatal编程技术网

Delphi 如何阻止访问TCustomListView中的Items属性?

Delphi 如何阻止访问TCustomListView中的Items属性?,delphi,delphi-xe,Delphi,Delphi Xe,我创建了一个自定义组件,它来自TCustomListView 我不需要发布项属性,也不需要代码在运行时访问该属性,因为我的自定义组件将处理项的填充和访问 我知道UnlistPublishedProperty,它可以包含在组件的寄存器过程中。考虑到这一点,我试着: UnlistPublishedProperty(TMyListView, 'Items'); 据我所知,上述操作只会使属性对对象检查器隐藏,因此通过代码MyListView1。项仍然存在 如何使项属性(或我猜的任何属性)成为用户不可见

我创建了一个自定义组件,它来自
TCustomListView

我不需要发布
属性,也不需要代码在运行时访问该属性,因为我的自定义组件将处理项的填充和访问

我知道
UnlistPublishedProperty
,它可以包含在组件的
寄存器
过程中。考虑到这一点,我试着:

UnlistPublishedProperty(TMyListView, 'Items');
据我所知,上述操作只会使属性对对象检查器隐藏,因此通过代码
MyListView1。项仍然存在

如何使
属性(或我猜的任何属性)成为用户不可见、不可访问的属性,但仍然可以由我的组件访问


谢谢。

您不需要
取消发布属性
来安排不发布属性。您可以选择不发布属性

要对代码以及设计师隐藏它,您就太倒霉了。你可以试试这个:

....
private
  property Items;
....
但它没有效果。从:

可以通过重新声明子类中的属性来提高其可见性,但不能降低其可见性


坦率地说,如果希望控件不公开此属性,则不应该从
TCustomListView
开始。也许您需要封装而不是继承

对于派生类,只能增加属性的可见性,而不能减少。由于Items属性在
TCustomListView
中是公共的,因此无法对组件的用户隐藏它。

据我所知,这是不可能的

有两种解决办法很接近:

  • 将ListView控件包装在您自己的控件中(例如,您创建了一个内部包含列表控件的控件)。内部控件与客户端区域对齐,不使用任何框架/边框等。声明您希望在外部控件上公开/发布的属性。框架等的属性应应用于外部控件,其他属性应转发给内部ListView控件
  • 创建自己的“ListView”控件(在内部转发到WinAPI ListView控件)。您可以复制VCL“TCustomListView”控件的几乎所有内容,并改为使用protected-on-Items。(如果您只是使用此控件,这应该不是问题。但是,由于版权问题,您不应该使用它创建第三方库)

  • 可以使用final来防止子类重写任何方法。如果您将该方法声明为严格私有,则该方法将不会在任何子类中由Code Insight显示。不确定这是否也适用于属性

    Delphi编译器还支持最终虚拟方法的概念。 当关键字final应用于虚拟方法时,没有子代 类可以重写该方法。使用final关键字是一个很好的例子 重要的设计决策,有助于记录类是如何运行的 打算使用的。它还可以向编译器提供允许它的提示 优化它生成的代码


    您可以在Items getter中引发一个异常,告诉程序员他的错误,并创建一个新的私有属性来存储列表内容


    并覆盖所有方法以正确引用新的右道具

    好的,我想我可能已经解决了我自己的问题。为此,我创建了一个新类,名为
    TMyListViewItems

    从源于
    TCustomListView
    的组件中,我在受保护字段中有我的
    Items
    属性,它是我上面描述的类

    类结构的片段如下所示:

      { TMyListViewItems }
      TMyListViewItems = class
      public
        constructor Create;
        destructor Destroy; override;
      end;
    
    { TMyListView }
      TMyListView = class(TCustomListView)
      private
        FItems: TMyListViewItems;
      protected
        property Items: TMyListViewItems read FItems;
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
      published
        // publish default listview type properties if needed here..
        property Align;
        property BevelEdges;
        property BevelInner;
        property BevelKind;
        property BevelOuter;
        property BorderStyle;
        property Color;
        property Font;
        property HideSelection;
        property IconOptions;
        property MultiSelect;
        property ParentColor;
        property ParentFont;
        property TabStop;
      end;
    
    t我的主要目标是在设计时或运行时,
    Items
    属性不再可见或可访问

    我发现的唯一缺点是,任何人都可以将其类型转换为
    TListView
    TCustomListView
    ,而原来的
    Items
    属性又回来了,但也许我不必担心这一点

    TListView(MyListView1).Items.Add.Caption := 'test';
    

    同上。封装似乎是前进的方向。请您详细介绍一下
    封装而不是继承。
    ?你这样说的确切含义是什么,再往下一步,围绕
    TCustomListControl
    构建我的组件?对不起,我理解了封装的概念,我的意思是我不确定到底封装了什么,正如Daniel所说,基本上有一个内部listview?这与所问的问题无关,作为
    TCustomListView.Items
    已经是公共属性。然后,您不能将其更改为在子体中的较低可见性,并添加
    final
    以隐藏公共
    项。这对代码编写者来说可能是个意外。您也在尝试hard@DavidHeffernan我现在明白了,我想拿一个现成的部件,把我不需要的东西切掉,而现在它似乎完全错了。最好重新思考我的整个方法,以满足我的需求