Delphi 如何创建只读属性?

Delphi 如何创建只读属性?,delphi,Delphi,我在运行时使用TMS对象检查器,但假设我的问题在设计时对Delphi同样有效 我希望有一个属性,它可以通过编程(在运行时)或硬编码(在设计时)进行设置。它应该对用户可见,因为信息对用户很有用,并且应该在运行时由程序更改,而不是由用户通过对象检查器更改 我试过了 published property FileName : String read FFileName; 属性是可见的,但在对象检查器中也可以更改(更改时会引发读取地址zer0异常):-(最简单的方法: private proced

我在运行时使用TMS对象检查器,但假设我的问题在设计时对Delphi同样有效

我希望有一个属性,它可以通过编程(在运行时)或硬编码(在设计时)进行设置。它应该对用户可见,因为信息对用户很有用,并且应该在运行时由程序更改,而不是由用户通过对象检查器更改

我试过了

published property FileName : String read FFileName;
属性是可见的,但在对象检查器中也可以更改(更改时会引发读取地址zer0异常):-(

最简单的方法:

private
  procedure SetFileName(Value: string);
published
  property FileName: string read FFileName write SetFileName;

....
procedure TMyClass.SetFileName(Value: string);
begin
  FFileName := FFileName;
end;

这看起来像是一个完全有效且正确的只读属性

published property FileName : String read FFileName;
如果您添加了一个额外的公共属性,因此只能在运行时进行设置,那么您就处于业务状态:

public property RuntimeFilename: string read FFileName write FFilename;
//note that two properties, one published and one public point to the same field.
但是,如果您想在设计时破解它并消除异常
将其更改为:

//Only writable during runtime.
private
  procedure SetFileName(Value: string);
published
  property FileName: string read FFileName write SetFileName;

....
procedure TMyClass.SetFileName(Value: string);
begin
  if csDesigning in Componentstate then {do nothing}
  else FFileName:= Value;
end;
我认为可能发生的事情…

断开设计时间和运行时代码之间的连接
要更改代码的运行时行为,只需更改源代码并删除属性的
write…
部分

但这不会影响设计时代码,因此需要重新安装组件。
如果您更改已注册组件的源代码,并将更改保留在组件的
私有
受保护
和/或
公共
部分,则通常可以

但是,如果您更改组件的
已发布的
部分,并且不重新安装该组件,则启动时会出现异常行为

这是因为在设计时您仍在使用组件的旧/未更改的二进制版本。此版本没有删除
写入部分
,并允许您更改基础字符串
FFilename

运行时初始化代码将读取表单资源1),并找到要写入FFilename的值。但是,过程
SetFilename
不再可用,因此在程序启动期间会发生访问冲突


1) (在.dfm文件中的数据,现在存储在.exe中的dfm资源中)

这显然是TMS对象检查器中的错误,您应该向TMS提交错误报告。

感谢您花时间回复。我已经尝试过了,但是用户可以通过对象检查器更改值,这是我不想要的。与所有其他属性一样,该属性具有白色背景,并且可以编辑。我希望它有一个灰色的背景(如字符串网格上的固定行),用户不得更改其值。(如果我们看不到如何做到这一点,我会将其私有化,但更愿意将其发布)是的,Mawg,该属性可以编辑。但编辑后,控件是否继续显示新的编辑值?不应该,因为基础字段的值没有更改。如果出现新值,则这是TMS控件中的另一个错误;在real Object Inspector中,Ken的代码将成功创建一个在设计时显示但忽略编辑它的尝试的属性。@Mawg:AFAICT,无法使只读属性显示为禁用状态。但用户应该很快明白,试图改变它是徒劳的;如@Rob所述,点击enter或left属性会将其恢复为上一个(只读)值。您一直假设TMS控件的工作方式与Delphi的Object Inspector相同。请停止那样做。没有。这一次,不同之处在于对象检查器甚至不显示只读属性,因此关于“读取地址0”的内容根本不适用,似乎是TMS的一个错误。@Rob,有一个设置可以切换,使Delphi对象检查器显示只读属性(或不显示)。它在工具->选项对话框的某个地方。快速解决方案:放下TMS属性检查器,使用绝地一号。它可能是设计出来的。哦,等等。。。除了碰撞部分。:-)