How to reference the control or name of control from datamethod of current string control?
Set the AutoDeclation property of the control to Yes, then use the control name directly.
Related
I created in Lazarus a new component based on TPaintBox. Now in Object Inspector I have all Properties and Events which belong to this base component (TPaintBox).
My question is: can I hide chosen Properties and Events for my component?
For example I would like to leave visible only Width and Height properties.
Can you help me?
Once a property/event has been published, it cannot be un-published.
However, it can be hidden from the Object Inspector, at least (it is still accessible to code).
After your design-time code has registered the component with the IDE, it can then:
in Delphi, call UnlistPublishedProperty() from the DesignIntf unit.
in Lazarus, call RegisterPropertyEditor() from the PropEdits unit to register the THiddenPropertyEditor class for the property/event (see Hide Properties (UnlistPublishedProperty) in the Lazarus forum).
Not sure about Lazarus, but in Delphi TPaintBox is a lightweight descendant of TGraphicControl. The majority of its declaration is just publishing properties. I don't know what your component is doing, but it might be easier to derive it directly from TGraphicControl and duplicate the TPaintBox code wherever it actually is needed. Then you can publish only the properties you want. Note that you still have those properties declared published in TControl and TComponent.
No, you can't hide (unpublish) published properties.
In Delphi most objects are based on a parent classes with all the same properties, but mostly hidden.
So while you can't hide exposed properties you can usually achieve what you want by basing your class on the TCustomxxx instead.
Sadly, TPaintbox is an exception. It is descended from TGraphicControl, but that in turn is descended from TControl which already has a number of published properties, including AlignWithMargins, CustomHint and several others, and that in turn is descended from TComponent which has Name and Tag published. To be fair, you need name for sure, and Tag is not a problem I would think.
If you just had to go back to TGraphicControl, that is not too bad. Just one member and a couple of routines to copy. But to go back to TComponent, which is what you would need to do to hide a number of properties is not really viable.
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.
How can I add a glyph property to my custom component?
Vcl.Buttons has declared class TButtonGlyph but I cannot use it (Delphi is not seeing it with Vcl.Buttons in uses list).
TButtonGlyph is an internal helper class used by the VCL. It's not what you need. I suspect that all you need to do is to declare a published property of type TPicture. The VCL will automatically provide a design time editor and can stream the image to the .dfm file. You can use any TGraphic descendent, including TPNGImage.
Is it possible to put a placeholder for a method call in the property value of an object in the Object Inspector? I have a method that returns a string that I'd like to include as part of the connection-string properties of some TADOConnection objects. Changing the method's return value would alter what gets assigned to each of the connections as they're loaded from the DFM.
I'm using RAD Studio 2010.
No, you cant. You can only have properties and events, but:
You can create a set method in you Connection property. This set method you search all forms and datamodules in you application and it will try to find an TADOConnection. When it finds one, it willl change its connection property. But this will only works in design time in the current form you put your component into, but it would work fine on runtime. Thats is not a pleasent solution, maybe you should try what #TommyA said on comments.
To avoid singletons and global variables I'd like to be able to pass parameters to a TFrame component. However since a TFrame normally is included on form at design time it is only possible to use the default constructor.
The parent form can of course set some properties in the OnCreate callback after the TFrame has been created. However this does not ensure that a property is not forgotten, and the dependencies are not as clear as using a constructor.
A nice way would be if it was possible to register a factory for creating components while the dfm file is being read. Then the required parameters could be passed to the TFrame constructor when created by the factory. Is there a way of accomplishing this?
Or does anyone have a better solution on how to pass parameters to a TFrame?
All components, including descendants of TFrame, need to be able to be constructed using the constructor inherited from TComponent. Otherwise, they can't be used properly at design time. If the restriction of design-time use is acceptable to you, then you could override that constructor and raise an exception. That would prevent the component from being placed on a form at design time. Simply provide some other constructor that requires other parameters.
Because of the design-time requirement, all components need to be able to exist with some or all of their properties still at their default values. That doesn't mean the components have to do useful things while they're in that state, but they do need to be able to stay in that state indefinitely. It should be OK, for example, to place a component on a form, save the form, and close Delphi, with the intention of resuming the form-designing at a later time. The component should allow itself to be saved and restored, even if all its properties haven't been set up for final use yet.
My preferred option is to enforce the component's rules only at run time. Check that all the properties are set to sensible values before you allow them to be used. You can use assertions to enforce the proper use of your components. Consumers of your classes will learn very quickly if they haven't finished setting up your components on their forms.
I would normally add a public, non-virtual "Initialise" or (Initialize to Americans) procedure which requires all parameters to be provided. This will then set the properties.
Make the properties protected or private if possible, so the only way they can be set is from calling Initialise(AFoo, ABar : integer).
Then in TFormXXX.FormCreate or TformXXX.Create, have:
inherited;
Initialise(foo, bar);
could you create/registercomponent your own tFrame component and
place that on the form - it's create could have anything passed to it.
If a factory could provide the parameters that you need, why don't you just override the default constructor for your frame, and ask the factory-class for parameters?
I usually make my own constructor. I don't like to create frames at designtime anyway.
a) a frame can be created dynamically when required and destroyed when not needed
b) give the frame a public property with either the parameter data type or a data structure and pass the values to the form through the property.
Example:
TAddress - a class to hold the usual elements of an address.
TAddressFra - a frame with the visual controls to display the address
populate an instance of TAddress with values
create an instance of TAddressFra
assign the TAddressFra.address property with the TAddress instance
use the procedure setAddress(o_address : TAddress) to assign the values of the TAddress attributes to the corresponding visual components on the TAddressFra