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) :-(
Read only means that we can access the value of a property but we can't assign a value to it. When a property does not have a set accessor then it is a read only property. For example in the person class we have a Gender property that has only a get accessor and doesn't have a set accessor.
You can use WriteOnly only at module level. This means the declaration context for a WriteOnly property must be a class, structure, or module, and cannot be a source file, namespace, or procedure. You can declare a property as WriteOnly , but not a variable.
If you need to make a read-only attribute in Python, you can turn your attribute into a property that delegates to an attribute with almost the same name, but with an underscore prefixed before the its name to note that it's private convention.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With