Reputation: 40140
I am using a TMS object inspector at run time, but assume my question would be equally valid for Delphi at design time.
I want to have a property which can be set programically (at run time) or hard coded (at design time). It should be visible to the user as the information is useful to him and it should be changeable at run-time by the program but not by the user via the object inspector.
I tried
published property FileName : String read FFileName;
and the property is visible, but it is also changeable in the object inspector (and throws a read of address zer0 exception when changed) :-(
Upvotes: 7
Views: 7608
Reputation: 2361
This is clearly a bug in the TMS object inspector and you should file a bug report with TMS.
Upvotes: 3
Reputation: 76537
This looks like a perfectly valid and correct read-only property
published property FileName : String read FFileName;
if you add an extra property that public and thus only settable during runtime you're in business:
public property RuntimeFilename: string read FFileName write FFilename;
//note that two properties, one published and one public point to the same field.
However if you want to hack it and get rid of the exception in Design-time
change it to:
//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;
What I think might also be going on...
Disconnect between designtime and runtime code
In order to change the runtime behaviour of the code you need only change the source code and remove the write ...
part of the property.
This will not effect the design-time code though, for that you need to reinstall the component.
If you change the source code of a registered component and you keep the changes within the private
, protected
and/or public
sections of the component you are usually OK.
However if you change the published
part of a component and you do not reinstall that component you will have abnormal behaviour at startup.
This is because in design-time you are still working with the old/unchanged binary versions of the component. This version has not had the write
part removed and allows you to change the underlying string FFilename
.
Come runtime the init-code will read the form resource 1) and spots a value to be written to FFilename. However the procedure SetFilename
is no longer available and therefore a access violation occurs during program startup.
1) (the data that was in the .dfm file and is now stored inside a dfm resource in your .exe)
Upvotes: 10
Reputation: 125620
The easiest way:
private
procedure SetFileName(Value: string);
published
property FileName: string read FFileName write SetFileName;
....
procedure TMyClass.SetFileName(Value: string);
begin
FFileName := FFileName;
end;
Upvotes: 3