【问题标题】:Is it possible? TCollection descendant to implement storage of TPanel containers with arbitrary content可能吗? TCollection 后代实现存储任意内容的 TPanel 容器
【发布时间】:2011-04-17 19:34:58
【问题描述】:

我是 Delphi 组件开发的新手,因此想知道,是否有可能实现我的任务。

我需要创建一个基于 TScrollBox 的可视组件(用户控件),它将代表一堆 TPanel,所有这些面板将在该 TScrollBox 内对齐为“顶部”,并且可以具有不同的高度。它必须充当 TCollection(添加、删除、重新排序),并且必须允许用户在设计时将其他控件添加到这些面板中。

我已经为组件创建了这些类:

type
  TPanelsGrid = class;

  TPanelsGridItem = class(TCollectionItem)
  private
    FPanel: TPanel;
    procedure SetPanel(Value: TPanel);
    function GetGrid: TPanelsGrid;
  protected
    function GetDisplayName: string; override;
  public
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
  published
    // This is my TPanel object that should be used at designtime
    // I thought "stored True" will serialize it automatically but I was wrong
    property Panel: TPanel read FPanel write SetPanel stored True; 
  end;

  TPanelsGridItems = class(TCollection)
  private
    FPanelsGrid: TPanelsGrid;
  protected
    function GetItem(Index: Integer): TPanelsGridItem;
    procedure SetItem(Index: Integer; Value: TPanelsGridItem);

    function GetOwner: TPersistent; override;
    procedure Update(Item: TCollectionItem); override;
  public
    property EditorsGrid: TPanelsGrid read FPanelsGrid;
    property Items[Index: Integer]: TPanelsGridItem
      read GetItem write SetItem; default;

    constructor Create(PanelsGrid: TPanelsGrid);
    function Add: TPanelsGridItem;
    procedure Delete(Index: Integer);
  end;

  TPanelsGrid = class(TScrollBox)
  private
    FItems: TPanelsGridItems;
    procedure SetItems(Value: TPanelsGridItems);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Items: TPanelsGridItems read FItems write SetItems;
  end;

这个组件在设计时工作正常,我可以在堆栈中添加-删除面板,当我在任何面板上放置一些控件(例如 TCheckbox)时,它显示为“由该面板拥有”:例如我无法将此复选框拖出面板。

但此复选框不存储在 DFM 文件中,也不显示在“结构”窗口中。

我想TPanel 的内容肯定有一些手动序列化-反序列化,但我不知道该怎么做。在 Internet 上找不到任何示例。请给我一些指导,如果这样的实现是可能的。

加法

这是在网格中添加 3 个面板后我的 DFM 文件片段的样子:

  object PanelsGrid1 : TPanelsGrid 
    Left = 8
    Top = 8
    Width = 536
    Height = 382
    Anchors = [akLeft, akTop, akRight, akBottom]
    TabOrder = 0
    Items = <
      item
      end
      item
      end
      item
      end>
  end

如您所见,所有项目都是空的,但我在项目 #3 中放置了一个复选框和单选按钮。

【问题讨论】:

  • 在设计时右键单击您的表单并选择“以文本形式查看”。如果您不介意,请找到与您的组件相关的部分并将其添加到您的帖子中。我自己也不确定这应该如何实现,但让我们先看看存储了什么。
  • 从 TComponents 继承的已发布属性不被流系统存储。
  • 他自己,完成,请看 dfm。
  • Uwe,所以我必须创建自己的流媒体程序?我应该从哪里开始?
  • 没有测试过(否则这将是一个答案):1)了解DefineProperties,2)尝试使面板成为子组件(ComponentState)

标签: delphi components delphi-2010 tcollection tcollectionitem


【解决方案1】:

毕竟我决定放弃使用 TCollection,因为在测试 DefineProperties 方法期间,我遇到了一致的 IDE 崩溃。我认为 TCollection 并不是为这样的任务而设计的。

我在控件 ExtCtrls.TCustomCategoryPanelGroup 内的 Delphi 源代码中创建了一个适当的实现。它维护可以在设计时和运行时添加或删除的面板堆栈。我使用 TCustomCategoryPanelGroup 和 TCustomCategoryPanel 的源代码创建了自己的类,它可以按我的意愿工作。

【讨论】:

    【解决方案2】:

    确保您的子面板具有名称。您可以覆盖 TCollection.Notify,如果 Action 是 cnAdded,请确保面板有名称。

    【讨论】:

      【解决方案3】:

      我觉得你可以看看TMS Poly List control

      TMS 高级多边形列表组件 提供了一个极其通用和 灵活的架构来创建 几乎所有可能的项目列表 在用户界面中。这是可见的 通常但不限于新 Office 2010 应用程序菜单。相反 对于大多数用户界面列表控件, 其中列表由 相同类型或项目的集合 同类型,TMS Advanced Poly 列表组件可以容纳多态 项目。所有项目只需要下降 从基类 TCustomItem 和 可以添加任何继承的项目。经颅磁刺激 高级 Poly List 组件来了 带有大量预建列表 项目,但自定义项目类可以 通过降序添加 TCustomItem 基类或任何 已经提供的课程。有 项目类显示为列表部分 项目,具有 HTML 格式的文本项目, 带有按钮的文本项,带有 展开/折叠行为,项目与 图像等等。物品可以 在多态列表中添加 设计时间,具有丰富的设计时间 编辑器和运行时通过代码。

      【讨论】:

      • 谢谢。太糟糕了,它已经关闭了源代码。但如果我在自己的代码中找不到解决方案,肯定会考虑购买。
      猜你喜欢
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 2012-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      相关资源
      最近更新 更多