Custom component properties LiveBindings - delphi

I've got problems with binding string properties to TLabel.
TGotManager = class(TComponent)
..
..
published
property HotQ1: String read FHotQ1 write SetHotQ1;
property HotQ2: string read FHotQ2 write SetHotQ2;
..
I did create a component because I don't want to use a TPrototypeDatasource.
My goal is to bind both properties to TLabel.text via the designer.
I did this with help from the answer here: Delphi: Making a component visible to live binding
Example 1:
//with this only HotQ1 is bindable via the designer.
[ObservableMember('HotQ1')]
TGotManager = class(TComponent)
Example 2:
//with this only HotQ2 is bindable via the designer.
[ObservableMember('HotQ1')]
[ObservableMember('HotQ2')]
TGotManager = class(TComponent)
The problem is that I only can bind one property via the designer. When dragging that property other ones which are compatible light up green. When dragging the second property the other ones stay red.

I don't get more then one property to work with visual Livebindings. I do get it to work via:
http://docwiki.embarcadero.com/RADStudio/Seattle/en/The_Entire_Project_and_Observing_the_Results
also for reference and automating things further this page from the Australian user group: http://www.adug.org.au/technical/vcl/using-livebindings-to-connect-the-ui-to-objects/
I don't accept this as an answer because this did not solve the problem. It provided a work around.

Related

Delphi: Property with combobox editor in Object Inspector. Get Form components in a list [duplicate]

This question already has an answer here:
How to create a component property that lists other components?
(1 answer)
Closed 8 years ago.
I want to edit published property in the Object Inspector via dropdown list.
Let's say it's DataSet: TDataSet.
I'm not started yet, but using this http://delphi.about.com/library/bluc/text/uc092501c.htm I will create a property editor and in GetValues method I should do some job to find out which components, that are descendats of TDataSet, are already on the Form that I'm designing now.
Yet didn't find any examples of it. How should I provide access to the current form inside my PropertyEditor.GetValues method or there is another approach?
Why it is NOT this: How to create a component property that lists other components?
Because at certain times in a drop-down list should be listed components of two or more types. At last - I need to hold in the Property a pointer to certain component, which would be not the same type, as it is declared.
I repeat: Property: TClassNone and shoud be listed there: TClassOne, TClassTwo and TClass Three, which are not descendatns of TClassNone.
All I think you need to do is make it a published property of your component and let Delphi's default property editor do its work:
type
TMyComponent = class(TComponent)
...
published
property DataSet: TDataSet read GetDataSet write SetDataSet;
end;
For example, I think TDataSource works like this without registering any special property editor for it.
Sorry, I was too hasty in writing the original answer. Here's an edit:
Write a descendant of TComponentProperty and override GetValues. Have a look at the TInterfaceProperty implementation in DesignEditors which filters the selection only to instances of components supporting the interface assignable to the property.

Can I connect a Delphi TEdit (or similar) simply to a published property of a class?

I've had this problem for years but maybe it is now possible to easilty solve it. I need to lay out a panel with several TEdit controls, each should show, and allow editing of, a published property of a class. Traditionally I would use TEdit (or a numeric derivative from the Raize or Developer Express libraries) and 'wire up' the OnKeyPress and OnExit events, convert between the edit text and the property type etc etc. All as per Delphi 1 (whose big birthday is soon!).
These days we have RTTI and Live Bindings, so ideally I'd like a way of telling a TEdit (or another similar control) about a single published property and the necessary 2-way link would then be established without all the wiring up and conversions. An object inspector does this job of course, but I'd like a more formal custom layout using labelled edit controls. It would be fine to simply cope with integer, float and string, and something like a TDBEdit where the field name was my property name would be great.
I've taken a look at the 'Bind Visually' designer (I have XE3) but I'm on to uncertain ground. Can anyone suggest a means of doing this? Thanks.
The comments above by Ken White and Sir Rufo are good pointers to the use of Live Bindings for wiring up components between each other, but I need to wire up controls to my own object and which is created at runtime. Further digging led me to this excellent article which pretty much does what I want. Jarrod's TBoundObject is intended to be the ancestor for your own objects, but by including an FObject field passed in the constructor and replacing his use of 'Self' by FObject, you can instantiate a standalone 'TObjectBinder' that easily connects various standard controls to published properties.

Date/Time Picker as Property Editor in a TCollectionItem descendant

I'm writing a component which requires properties of type Date, Time, and Date/Time. I would like these properties to be visible in the Object Inspector, with an option to use a popup property editor.
I have tried TDate as a published property, and this gives me the results I need for just Date alone. However I need the same thing for TTime and TDateTime but they don't come with a property editor, and in fact it won't even accept any value I type in there either.
I have found the TDateTimeProperty which can be used as a property editor, or so I understand anyway. I have done the necessary implementation when registering this component. This property I need to apply it to is actually a TCollectionItem descendant, not necessarily a part of the component but within it.
This is how I'm registering it...
RegisterComponents('My Page', [TMyComponent]);
RegisterPropertyEditor(TypeInfo(TDateTime), TMyCollectionItem, 'MyPropName', TDateTimeProperty);
Although this compiles, when I install it, there is no property editor on this property. I have tried using my component's class name in place of TMyCollectionItem but same issue.
What am I doing wrong here to show this property editor?
You don't need to register the built-in property editors for TDateTime, TDate and TTime. They are already registered. That's why your attempts to register them have no impact.
The built-in property editors for these types simply convert between the underlying floating point value and a string representation. They don't implement date time pickers or anything like that.
You say:
However I need the same thing for TTime and TDateTime but they don't come with a property editor, and in fact it won't even accept any value I type in there either.
That is in fact incorrect. They do come with property editors. They are the same built-in property editors that you named in your question. And they do accept values. They don't accept the values you provided because you provided invalid values.
If you want to register a property editor that does provide a visual date time picker, then you will have to write the property editor yourself.

Is there a component to automatically create a config form?

I have a settings class in my system, where I store configuration values for important settings. It looks like the code below, but with many more attributes of different types.
Now I need to implement a form with which I can adjust and configure these settings at runtime. Its very cumbersome to implement the fields for each attibute and guarantee that all values are mapped without error.
Now my question: is a vcl component that could automatically create an interface to solve that. Eg. offer a tree-like or listview-like interface with the names of the attributes and fields to edit the values (like the property pane in the IDE, with printer settings, see screenshot below). That would be a great thing. No?
How do you deal with configuration forms like that?
Thanks for your input!
TGoldmannSettings = class
private
FInitialSymbolSize : Integer;
FPenWidth : Single;
FCanvasColor : TColor;
FShowLiveCoordinates : Boolean;
FFont1 : TFont;
FMsmPointSymbol : TAvailableSymbols; // own type
...
public
constructor Create;
destructor Destroy; override;
property SymbolSize : Integer read FInitialSymbolSize write FInitialSymbolSize;
property Font1: TFont read FFont1 write FFont1;
...
published
property PenWidth: Single read FPenWidth write FPenWidth;
property CanvasColor: TColor read FCanvasColor write FCanvasColor;
property ShowLiveCoordinates: Boolean read FShowLiveCoordinates write FShowLiveCoordinates;
...
end;
You sometimes find something I mean in printer setting dialogs:
The TJVInspector component from the Delphi Jedi JVCL project creates a property editor very similar to what you are looking for. They have an advanced example that works on an INI file.
JVCL Site: http://jvcl.delphi-jedi.org/
Nice example: http://www.neugls.info/?tag=tjvinspector
The JVCL / JCL package is huge but has a ton of useful components and functionality.
I have never yet created an automatic-configuration form generator similar to the one in the delphi project options, but I have seen this done in several projects that I work on, and seen the source code, and it works very much like this:
I would have a base type of frame called TConfigFrameBase and it would contain some properties like this: Caption (user displayed name of property), Hint (some help), and Name (config property), and Section (page this property is shown on).
Specialized inherited frames would be used for boolean properties, string properties, etc. Your domain (your app) will have its own custom types. Dates? Lists of apothecary locations in Denmark? Only you know for sure the complete set of UI configuration property types you need, and that's why I haven't seen a component that makes this automatic or just a component. The boolean frame would contain a Label control and a checkbox and would have a default height around 30 pixels. A frame that let me move a list of options on side A to options on side B (columns visible within a particular grid, for instance) might be as high as 300 pixels. By vertically stacking these frames, in a scrollbox, you don't have to do much thought about layout. Everything will be usable when these frames are used to populate a listbox.
A tree view on the left that lets you pick a section. In the on-click in the tree view, the right side pane is built by iterating through my internal list of config-frames that are registered in a list or dictionary, and filtered by the Section they belong to.
I wouldn't use a JVCL Property Inspector as my configuration control, but it might work for you. I also don't think you're going to get everything you need out of VirtualTreeView, but your mileage might vary. You can write your own custom Editor controls, and if you like writing in-place-editor controls, you might find VirtualTreeView perfect.

What's the difference between public and published class members in Delphi?

Please could someone explain me what's the difference between public and published class members in Delphi?
I tried to look at Delphi help and I understand that these members have the same visibility, but I don't understand very well how they differ and when should I use published members instead of public ones.
Thanks a lot.
The compiler generates RTTI (Run-Time Type Information) metadata for published members, but not for public members (by default). The main effect of this is that the published properties of an object will appear in the Object Inspector at design time.
I do not know if you are writing components, but if you do, you probably know that properties and events are normally published, so that they can be set using the Object Inspector.
Public
public
property MyProperty: integer read FMyProperty write FMyProperty
MyProperty will not be visible in the Object Inspector.
Published
published
property MyProperty: integer read FMyProperty write FMyProperty
MyProperty will be visible in the Object Inspector.
Public properties and published properties have the same visibility, as you already stated. Published properties are included in RTTI, public properties aren't.
As a side note, there is another special thing with published:
The default visibility of class members is published, so check for unsafe code like:
TTopSecret = class(TObject)
Name: string;
Password: string;
function DecryptPassword(const AValue): string;
public
constructor Create(const AName, AEncryptedPassword: string);
end;
Name, Password and DecryptPassword() are visible 'world-wide'.
Published properties will export Runtime Type Information (RTTI).
Have a look here about RTTI in Delphi
It seems there are lots of good answers already, pointing out the Object INspector, RTTI,
etc. These are all pieces of the puzzle.
If you take away the published keyword, the entire Delphi RAD tool design would require some way to specify which properties are stored in a DFM, inspected in the component property inspector, and can be reloaded at runtime from a DFM when the form or data module is created.
This, in a word, is what Published is for. It is interesting to me that the designers of QT (originally TrollTech, later part of Nokia, later still spun off to Digia) had to emulate this level of RTTI for their C++ RAD library "QT", adding a "published" equivalent and a "property" equivalent, while pure C++ still lacks this fundamental facility.
Runtime Type Informations (RTTI) are only generated for published class members.
At run-time, entries in the published and public sections are equally accessible.
The principal difference between them is that published items of a component appear in the Object Inspector at design-time.
This happens because, for fields in published section RTTI is automatically generated.
The Object Inspector picks this up and uses it to identify what to add to its list of properties and events.
In addition to the other answers:
Published properties are automatically stored by the streaming system.
For instance if you have a TComponent's descendant instance and write it to a TStream with WriteComponent, all (well, not all, but that is another question) published properties are written to the stream without any further coding.
Of course, the streaming system only can do that because the RTTI is available for those published properties.

Resources