【问题标题】:delphi component property dynamic valuedelphi组件属性动态值
【发布时间】:2016-08-06 20:41:47
【问题描述】:

如何获取组件属性变量的动态值

在我的组件中,我有一个名为 ColorDefault 的字段,我希望能够在程序中动态设置它的值。

原始代码

var // global
  _V_TB_DefaultColor: TColor

type
  TMyClass = class
  ...
  property ColorDefault: tcolor read _V_TB_DefaultColor write FDefaultColor;
  //[dcc32 Error] MyButton.pas(85): E2168 Field or method identifier expected
  ...
  end;

编辑:

我按照汤姆描述的方式进行了如下操作,但是颜色没有根据全局变量而改变,颜色保持在编译时的状态,例如我的全局颜色是 clyellow,我编译了我的组件并将其放在表单上,​​然后我将全局颜色变量更改为 clwhite,当我运行程序时它仍然是 clyellow

type
  TTestClass = class(TPanel)
  private
    { Private declarations }
  protected
    { Protected declarations }
    FColorDefault:tcolor;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function GetGlobalColorVariable:TColor;
  published
    { Published declarations }
    property DefaultColor:TColor read GetGlobalColorVariable write FColorDefault;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MyComponents', [TTestClass]);
end;


constructor TTestClass.Create(AOwner: TComponent);
begin
  ColorInitiate;
  inherited;
  color:=DefaultColor;
end;

destructor TTestClass.Destroy;
begin
  inherited;
end;

function TTestClass.GetGlobalColorVariable: TColor;
begin
  result:=_V_TB_DefaultColor;
end;

end.

【问题讨论】:

  • 如果你想从另一个变量中读取属性值,FDefaultColor 字段没有多大意义
  • 我没有看到ColorDefault 的任何属性声明,也没有看到_V_TB_DefaultColor 的任何声明。请与您的标识符保持一致。这个问题与您最初提出的问题不同,并且变得一团糟。您是否阅读过有关属性的文档?如果你想改变一个属性,你必须给它分配一个新值。
  • 如果您希望 ColorDefault 属性发生变化,只需更改 _V_TB_DefaultColor 答案是否定的,这不会发生,没有这样的自动。我在答案中添加了一段关于此的内容。
  • 请@Emre,不要更改您的帖子,以免以前写的答案失效。在这些情况下,最好添加新代码而不删除旧代码。我从您的第一个 cmets 添加了代码,所以让我们清理和删除过时的 cmets。如果您将鼠标移到您的评论上,您的评论后会出现一个圆形按钮。用它来删除。
  • @TomBrunberg 抱歉,我需要习惯使用论坛 :) 我确实删除了我的 cmets

标签: delphi variables components


【解决方案1】:

查看您的问题,您似乎正在处理两个问题。

第一个问题是如何使用属性访问一些全局变量。

您可以像这样使用属性的 Getter 方法来做到这一点:

type
  TTestClass = class(TPanel)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    function GetDefaultColor: TColor;
  published
    { Published declarations }
    property DefaultColor: TColor read GetDefaultColor;
  end;

var // global
  _V_TB_DefaultColor: TColor

implementation

function TTestClass.GetGlobalColorVariable: TColor;
begin
  result := _V_TB_DefaultColor;
end;

就像您在问题编辑中所做的那样。这将始终使您的 DefaultColor 属性返回与存储在全局 _V_TB_DefaultColor 变量中相同的值。

但请注意,这不会检测到 _V_TB_DefaultColor 变量何时更改。因此,如果您想在更改后更新您的组件,您需要自己为每个组件执行一些更新过程。

还要记住,像这样使用全局变量并不是一个好习惯。

如果您希望所有组件的某些属性具有相同的值,最好将该属性声明为类属性,如下面的代码所示。

type
  TTestClass = class(TPanel)
  private
    { Private declarations }
    class var FDefaultColor: TColot;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    class function GetDefaultColor: TColor;
  published
    { Published declarations }
    class property DefaultColor: TColor read FDefaultColor write FDefaultColor;
  end;

现在更改一个组件中的 DefaultColor 将更改同一类的所有组件的 DefaultColor。但请记住,您仍然必须为每个组件执行正确的过程以更新自身。这不会自动完成。


现在您的第二个问题是检测 DefaultColor 变量的变化并相应地更新您的组件。

现在,如果您使用全局变量,则没有机制可以检测到这一点。但是,如果您使用的是类过程,那么您至少可以编写一个 setter 方法,该方法将执行所有需要更新的组件的更新方法,或者向它们发送必要的通知,以便它们自己执行必要的更新。

如何实现?

一种方法是遍历所有表单组件,检查它们的类型并执行必要的更新过程。但是,如果您有很多其他组件需要检查它们是否正确,那么这可能会很慢。

另一种可能更好的方法是将您的组件添加到单独的列表中,这样您就不需要进行类型检查,因为您知道这样的列表只包含正确的组件。

【讨论】:

  • 谢谢,通过您的解释,我了解了如何在自定义组件中使用全局变量以及如何在组件上获取/应用更改,我必须使用函数来获取我的属性字段全局变量的值和(在运行时)在全局变量的值更改时通知/应用新值我必须使用触发器
【解决方案2】:

您需要查看有关属性的文档 http://docwiki.embarcadero.com/RADStudio/XE7/en/Properties

你的代码

property ColorDefault:tcolor read _V_TB_DefaultColor write FDefaultColor;

未被编译器批准,因为_V_TB_DefaultColor 不是您的类的字段或方法。该属性可能应该声明为:

property ColorDefault:tcolor read FDefaultColor write FDefaultColor;

要设置FDefaultColor等于全局变量_V_TB_DefaultColor,你需要

MyClass.ColorDefault := _V_TB_DefaultColor;

在你的代码中一个合适的地方,你的类的构造函数中的 f.ex。

请注意,要更改组件的颜色,您需要为 ColorDefault 属性分配一个新值。更改全局变量 _V_TB_DefaultColor 的值不会自动更改属性的值。


在您添加的修改后的代码中

function TTestClass.GetGlobalColorVariable: TColor;
begin
  result:=_V_TB_DefaultColor;
end;

如果您不将函数的结果分配给某物,那将不会做任何事情。既然函数是TTestCalss的成员,相信你想 直接在这个函数中设置Color属性:

function TTestClass.GetGlobalColorVariable: TColor;
begin
  Color:=_V_TB_DefaultColor;
end;

如果是这种情况,您可以将其更改为procedure,因为您不使用返回值:

procedure TTestClass.GetGlobalColorVariable;
begin
  Color:=_V_TB_DefaultColor;
end;

【讨论】:

  • @Tom Brunberg 关于“自动更改” - 我们可以将read GetDefaultColor 视为自动更改,其中GetDefaultColor 是读取全局变量的函数。但是FDefaultColor 字段变得毫无用处。
  • @MBo 是的,但是仍然需要触发 getter。改变全局不会那样做。
  • @Tom Brunberg 目前尚不清楚他是否曾经使用过 FDefaultColor 字段。如果没有,getter 可能会有所帮助。
  • @MBo 确实我们不知道。我会在Paint 中使用它,我希望 Emre 也会这样做。
【解决方案3】:

谢谢大家,

根据所有建议,我所做的是使用函数从全局变量中获取值并使用 Windows 消息作为触发器将新值应用于组件

【讨论】:

    猜你喜欢
    • 2011-01-05
    • 2020-05-21
    • 2016-03-17
    • 2020-09-30
    • 1970-01-01
    • 2018-12-25
    • 2021-09-20
    • 2010-11-23
    • 2017-04-09
    相关资源
    最近更新 更多