Why some properties are hidden from Object Inspector when more than one item is selected? - delphi

I've noticed that some properties disappear from the Object Inspector when selecting more than one item.
Why does this happen and how to control this behavior when creating a component?
Example:
Add 2 buttons (TButton) to a form and select one of them.
In the Object Inspector you can see all TButton's published properties (Note that there's also the Constraints property).
Add the other button to the current selection (Click while pressing Shift key).
As you can see, some properties have been hidden from Object Inspector (Note that the Constraints is no more visible).

Whether a property is displayed when multiple objects are selected is controlled by the property editor configured for that property. Property editors (descended from TPropertyEditor in DesignEditors.pas) have a GetAttributes method that returns a set of attributes that apply to the editor. If the set includes paMultiSelect, then the property will be displayed.
Given that the property value is displayed as the constraint values, rather than just (TSizeConstraints), I conclude that that property is not using the generic TClassProperty editor. That editor sets paMultiSelect, but based on your pictures, the property editor to TSizeConstraints doesn't. It was probably an oversight.
You could try registering your own property editor. Find the property editor currently registered for TSizeConstraints (by searching the source code for TSizeConstraints, for instance) and, in a design-time package, declare a new class descended from that one. Override GetAttributes to return the value you need. Finally, follow examples elsewhere in the code to call RegisterPropertyEditor.

Related

(delphi) how to add property to child controls?

In the Delphi IDE, some components in Delphi have the ability to "add" properties to the child controls they contain in the property editor.
How can I achieve the same thing with my own TCustomPanel descendant?
Some more details:
What I want to achieve is the following: I have a very complex configuration dialog for an application with a large number of visual components.
I want to add to each of these components a "complexity index" (an integer) that will be used to show or hide the component based on a selection made by the user (a dropdown with "simple", "advanced" and "expert" options).
I understand that the property will actually belong to the parent panel but I need a way to display it, in the IDE, as if it was attached to the control it is related to.
The perfect exemples are the various "organizational" panels provided by Delphi: TGridPanel and TRelativePanel. Each of these have a ControlCollection (published) properties that is used to hold the actual states of the additional properties but I failed to locate how the property editor knows that it must attach the properties to the child controls.
Here is a screenshot of a TLabel placed inside a TRelativePanel with the relevant properties highlighted:

How to use two properties for a single property editor?

Refer to this prior question/answer combo of mine. It's describing how to create a property editor for the IDE.
I've created another property editor for a completely different purpose. In this case, it's a glyph character selector of type String (because it could contain more than one glyph character). Unlike my other one in mentioned question/answer, this one is very specific to a particular property on a particular TCollectionItem class of mine.
All is good, and I can invoke this property editor for this particular property. However, I have a dilemma. The property editor, by nature, is directly related to a font. The user may choose a character (glyph) from a particular font. My property editor has the facility to change the font, and browse the glyphs contained within that font.
This component of mine also has the facility to specify the font, in a separate TFont property. The problem arises when it comes to the combination of both my Glyph property and Font property being used in the very same property editor. When I invoke this editor for the Glyph property, it also needs to know the Font which it needs to use. On the contrary, when user chooses a font and glyph character in this editor, it also needs to update both the Glyph and Font properties.
Long story short, PropertyB depends on PropertyA. If PropertyA changes, then PropertyB will have an entirely different set of possible values. So, whatever editor I install in the IDE needs to allow the user to change both PropertyA and PropertyB at the same time.
How can I make a property editor have access to more than one property?
TPropertyEditor has a public GetComponent() method that you can use to access the object(s) whose property is currently being edited (multiple objects with the same property can be edited at the same time, if the property editor allows it). Then you will have access to all of the other properties in the same object(s).
That being said, if your editor displays a pop-up dialog for editing, it should be implemented as a component editor instead of (or in addition to) a property editor. A property editor should edit only one property at a time, though it may have read-only dependancies on other properties. For instance, a Glyph property editor that also edits the Font property, and vice versa, is not a good design. But a component editor that edits both is perfectly acceptable.
Solution 1
Instead of a property editor, implement a component editor. Such a component editor will have access to the entire component, not just a single property.
Solution 2
Wrap both of your properties inside of a dedicated TPersistent class, and then create a TClassProperty property editor for this class instead. The individual properties will not actually invoke a property editor. Instead, their parent TPersistent will invoke a combined property editor which has access to all the properties within this class. A good existing example is the TFont editor.

AfterOpen TcxDBcurrencyEdit

I 'm using Delphi 7.
I want to use TcxdbcurrencyEdit instead of using TDBEdit, but the probleme I didn't find the AfterOpen events when affecting my datasource to my component.
thanks in advance
A TDBEdit does not have events like AfterOpen, AfterCancel, OnNewRecord - they are all events of a TDataSet, not a TDBEdit. So, if you want to access those you need to select your dataset in the Object Inspector, then click its Events tab.
Now that you've added some more explanation in your "answer", I follow what you're saying. In the Object Inspector, on the Events tab for a DBEdit, above OnChange, OnClick etc, there is a red label DataSource and if you expand it you can see a label DataSet and, if you expand that, you can see its events.
Where your confusion is arising is that I think you've missed the point that what the Object Inspector is showing you is just the DataSource connected to the TDBEdit (via its DataSource property on the OI's Properties tab) and the DataSet to which the DataSource's DataSet property is set. These DataSource and DataSet objects are the ones on your form (or datamodule if you're using one), and the red DataSource label of the DBEdit's Events tab is just a quick way of showing you relevant properties of them. If you want to inspect them in full, you just click them on the form as usual to select them for the Object Inspector. So, to see the DataSet's Event, just click it on your form and then click its Events tab in the Object Inspector. It's that simple!
Its true that there is no similar red DataSource label for a TcxCurrencyEdit, but that's just because its developers have chosen to omit that from what the Object Inspector shows - it does not mean that associated DataSource + DataSet and its events are missing.
[Original]
Assuming you have a TDataSet and a TDataSource on your form, to add a TcxDBCurrencyEdit all you need do is to drop one on your form, then, in the Object Inspector, click on the '+' sign next to its DataBinding property to expand it, then set its DataSource property to your DataSource and its DataField property to the name of your currency field.

Removing properties from Object Inspector

I bought the TMS Component pack and want to hide some component properties from displaying in the object inspector.
I am using UnlistPublishedProperty to hide them.
It works most of the time. But for some reason e.g. Anchors or StyleSettings are still displayed.
I am calling it like this:
UnlistPublishedProperty(TAdvEdit, 'StyleElements');
The weird thing is that it works on 90% of properties and i can't figure out why it will not hide the other properties from the object inspector.
I could edit the source and comment out the line where it gets published from TCustomEdit but i am wondering why the method with UnlistPublishedProperty isn't working.
Thanks!
The properties you are trying to remove are inherited from a higher ancestor class. If you wish to use UnlistPublishedProperty to remove these particular properties, you'll have to remove them from the ancestor. However, that would apply to all controls, not just the one you're working on.
In addition to Jerry's answer; there is a solution for deleting properties from sub-components. The third part of my answer here demonstrates how to filter out properties of a sub-component of a custom component by registering a component PropertyEditor and overriding GetProperties to filter specific property names.

How to put my published properties into the specified category of Object Inspector?

I have my own visual component. It has many published properties and events. I want them to be shown in the specified standard categories of Object Inspector at design-time (Visual, Layout, Drag Drop / Docking, Linkage etc).
Now all my properties are in the Miscellaneous category.
You can use RegisterPropertyInCategory function, defined in the DesignIntf. Example.

Resources