In want to use LiveBindings in Delphi XE5. I am new to this.
I have a VCL TForm with a TEdit.
I have a component in a seperate unit:
TMyComponent=class(TComponent)
private
FMyProperty: Integer;
public
property MyProperty: Integer read FMyProperty write FMyProperty;
end;
Now I want to bind MyProperty to the TEdit.
I tried this with right clicking on the TEdit and select "Bind visually" as well as with the LiveBindings wizard. The problem is that the MyComponent is not listed in the components list there.
The unit which contains MyComponent is in the uses clause of the form.
What am I doing wrong?
Thanks!
The IDE only knows about component classes that have been registered with it. To make this work at design-time, you need to build a package that registers the component class. Otherwise, you'll need to create the bindings programmatically. I'm not particularly familiar with the LiveBindings system, but there are several questions in the livebindings tag that show how it's done.
Related
I have added a published event to my main form, expeecting it would show up in the editor, but it doesn't.
Am I doing something wrong, or is this just not the case?
THIFISongEndEvent = procedure(Sender: TObject; EstimatedEndTime: TDateTime) of object;
TMain = class(TForm)
[...]
published
property OnSongEnd: THIFISongEndEvent read FOnSongEnd write SetOnSongEnd;
EDIT: Added Code
Published properties of TComponent descendants are visible in the Object Inspector only when these components are registered in a design-time package. Otherwise, you would not even be able to drop the component onto the Form.
As Forms are usually designed in the Form Designer, they are probably not registered for design-time, and thus their published properties added on top of the base TForm properties cannot be known by the Object Inspector.
I created a simple design-time component that helps to select and bring to front other components on the same form. (It is more convenient than IDE object tree view when designing full screen forms in a single monitor environment). But in Delphi XE2, I cannot reliably ensure and detect that the helper component itself is on the top. When I select it, the IDE draws 8 blue balls as a marker around it, and it seems to me that those markers are part of the actual top level window.
So, how could I check if a component is selected in the IDE designer?
So, how could I check if a component is selected in the IDE designer?
Create a design-time editor for your component (make sure you implement it in a designtime-only package, not a runtime package), and register it with RegisterComponentEditor(). TComponentEditor has a Designer property to access the Form Designer's IDesigner interface, which has a GetSelections() method:
procedure GetSelections(const List: IDesignerSelections);
IDesignerSelections has Count and Items[] properties, where Items[] returns a TPersistent object. So you can loop through the list looking for your desired component object(s) (all components derive from TPersistent).
IDesigner also has SelectComponent() and SetSelections() methods, so you can have the Form Designer select other components as needed:
procedure SelectComponent(Instance: TPersistent); overload;
procedure SelectComponent(const ADesignObject: IDesignObject); overload;
procedure SetSelections(const List: IDesignerSelections);
So basically here is what I did:
I made a new FMHD Application and dropped a TTabControl and a Button on it. Then I designed an interface IFoo. To keep it simple, let's just pretend it only has one procedure:
type
IFoo = interface
['{D035-N07-M4773R-...}']
procedure makeTab(tc : TTabControl);
End;
I implemented this interface in a DLL. The DLL is loaded via LoadLibrary and exports a
function getFoo : IFoo;
MakeTab basically creates a TTabItem and sets tc as it's parent:
procedure TFoo.makeTab(tc : TTabControl);
var
tab
: TTabItem;
begin
tab := TTabItem.Create(tc);
tab.text := 'Hi, I am Tab';
tab.Parent := tc;
// ...
end;
If I forgot something, I am very sorry. I do not have the exact source in front of me at the moment.
This method is invoked when the Button on the form is pressed.
But nothing happens.
So I put this method into my TForm1 class. If I call it now, a tab is created.
So how can I create this tab (and several child components) from within the DLL on the application's main form?
The fundamental issue here is that you cannot share Delphi class types between modules using DLLs. The reason is that there will be multiple versions of what needs to be a single type. One version in the executable, and one version in each DLL that uses it.
This is the same well known issue that exists with the VCL and is the reason why runtime packages were developed. And that's your solution for FMX also. If you need to share Delphi class types between modules you need there to be one single definition of a type. And runtime packages are the mechanism that makes that possible.
So, stop using DLLs, move the code into a runtime package, make sure that the RTL and FMX are linked using runtime packages, and that problem will be solved.
Tool: Delphi 6 Pro
I created a new component in my main components package that is a descendant of TFrame using the Component -> New Component option. When I try to draw the component on a form during design time I get a "Resource {component class name} not found" error. I tried adding the line {$R *.dfm} to the component unit just after the "implementation" declaration and that didn't work. (I did recompile the host package first). I even tried copying over a DFM from another frame and then renaming everything to sync up with the main unit including the DFM file name itself. That didn't work either.
I want to have the TFrame descendant as a Component instead of just creating a new TFrame variant because I want to add properties to it that show up in the Property Editor at design time. Is there a way to make this work?
Thanks in advance.
Can you publish the properties of a control that is inside an ActiveX form?
Example: I have a form with an TADOConnection component. I wish that the properties of this component can be modified by the user when he loads my ActiveX control.
UPDATE
#TOndrej gives me a very nice sample, but this sample only works for components derived from an ActiveX control. How can I accomplish this same effect with a VCL component like a TImage or TMemo? Is it possible to publish all the properties without rewriting each property to expose them manually?
ADO components are already ActiveX objects, so the easiest way is to expose the connection as a simple property of your ActiveX form:
In the type library editor, add "Microsoft ActiveX Data Objects 2.1 Library" to the list of used libraries. This will generate ADODB_TLB.pas unit in your project directory.
Then you can declare a new read-only property Connection of type Connection (this type is declared in ADODB_TLB unit) in your IActiveFormX interface.
In the implementation, you can simply return the interface from your TADOConnection component:
type
THackADOConnection = class(TADOConnection);
function TActiveFormX.Get_Connection: Connection;
begin
Result := Connection(THackADOConnection(ADOConnection).ConnectionObject);
end;
The THackADOConnection typecast is only necessary because ConnectionObject is protected. The outer Connection typecast is there to get rid of the compiler error "Incompatible types: ADODB_TLB._Connection and ADOInt._Connection."