【问题标题】:Delphi: Can we use metaclass reference to access properties at runtime or designtime?Delphi:我们可以在运行时或设计时使用元类引用来访问属性吗?
【发布时间】:2012-10-02 07:39:06
【问题描述】:

问题源于需要为不同类型的对象重用代码。

  • 场景:

从不同的列表框或相同的列表框拖放到列表框中。
当我尝试在同一个控件中实现拖放时,会出现上述问题。
用户可以通过向上或向下拖动来重新排列列表框中的项目。
我已经写了逻辑,它有效。
问题是,在我的应用程序中,我根据要求使用了不同类型的列表框。
所以他们的类型会改变。为了使用相同的代码进行拖放,
当源和发件人相同时,我将不同的列表框类型转换为共同祖先 TCustomListBox
然后将其发送到执行项目移动的函数。
该函数将项目集合中的项目交换到它们的新位置。

  • 现在特定场景:

    我使用了一个复选框,其中每个项目都有一个复选框。
    碰巧的是,每个项目都有一个关联的 checkstate 对象。
    现在在函数中,为了移动项目,我使用 tstringlist 临时存储项目
    及其对象,然后从控件中删除它们,然后将它们重新插入控件中。
    但在此复选框的情况下,当我删除一个项目时,该项目会被删除,
    但其对应的 checkstate 对象仍然存在,并与下一项相关联,
    这是不希望的。
    所以现在我使用一个 int 变量作为正常的模式指示器,
    和特殊的拖放。
    当它很特殊时,例如在 checklistbox 的情况下,我将其类型转换为 tchecklist 和
    然后访问它的删除方法,该方法会删除项目及其检查状态。

    所以我想知道,而不是使用 int 作为模式,
    我是否可以使用所有列表框的基类的类引用和
    那么如果需要,我如何访问特定列表框类型的属性。
    上述解决方案不是最佳的,这就是为什么,我需要一个更通用和正确的方法。 看看你能不能帮忙。谢谢。感谢您的建议,我很关心这个社区,我不习惯编辑功能。对不起。

我正在使用 delphi 6。
函数声明如下:-
DragDropItemsInListBox(p_HostIndex : Integer; p_HostListBox : TCustomListBox;
p_Mode:整数);

致电:-
hostindex 是放置站点索引,hostlistbox 是要放置项目的控件,
在这种情况下,源控件和目标控件是相同的,
mode 表示删除的方式。
DragDropItemsInListBox(3,TCustomListBox(Source), 1);


如果模式为 0,那么我通常会删除项目,如下所示:-
p_HostListBox.items.delete(i);

如果是1,表示特殊处理,
在这种情况下,我知道该怎么做,因此我使用,

如果 p_Mode = 1 则
(p_HostListBox as TRzCheckList).items.delete(i);


这将删除该项目以及 checkstate 对象。
但我不想依赖这种基于 int 的差异化。
我可以使用元类吗?如果我通常调用 items.delete,
那么它是否适用于该特定类型?

【问题讨论】:

  • 请指定您正在使用的 Delphi 版本,因为这会严重影响可能的解决方案。如果您向我们展示您当前源代码的相关部分,也会有所帮助。
  • 呃。请格式化您的问题,使其易于阅读。编辑问题并添加换行符。使用实时预览查看它的外观。向我们表明您对此事的关心足以让我们也关心。

标签: delphi


【解决方案1】:

因此我使用,如果 p_Mode = 1 then (p_HostListBox as TRzCheckList).items.delete(i);

这将删除该项目以及 checkstate 对象。但我不 想依靠这种基于 int 的差异化。我可以使用元类吗 如果我通常调用 items.delete,那么它是否适用于 具体类型?

您不能使用元类变量 - 元类指针对于该类型的所有对象都是相同的。如果 Delphi 允许这样做 - 将无法知道要从哪个清单中删除。

但是使用 int 确实是一个糟糕的解决方案。

if p_HostListBox is TRzCheckList 
   then TRzCheckList(p_HostListBox).items.delete(i); 

旁注:在 Component Pascal 中会有更多的糖:IS 暗示在那里:如果 p_HostListBox 是 TRzCheckList 那么 p_HostListBox.items.delete(i);

可能是阅读有关 RzChkLst.TRzCheckList.Items 帮助的更好方法 - 这是 TStrings 类型的属性。

修改声明

procedure DragDropItemsInListBox(p_HostIndex : Integer; p_HostListBox : TCustomListBox; p_Items : TStrings);

将其称为 DragDropItemsInListBox(0, RzCheckList1, RzCheckList1.Items);

在程序中做

p_Items.Delete(i);

【讨论】:

  • 感谢您的帮助。这似乎是更好的方法。会试试这个。
猜你喜欢
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多