Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: How to publish sub-events in a component


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 12 - Last Post: Dec 22, 2017 5:21 PM Last Post By: Brandon Staggs Threads: [ Previous | Next ]
Brent Rose

Posts: 126
Registered: 9/23/00
How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 19, 2017 8:57 PM
I have a component that uses a custom property class to group some custom properties and events.

On the Object Inspector properties tab, my property class appears as expected, with the defined sub-properties below it. However, the events of the property class do not appear on the events tab at all. Is there something more I need to do to publish the events? Thanks.

Here is some simplified code creating a "TTestEditor " derived from TEdit which reproduces the problem as described:

type
TCustomTestProperties = class(TPersistent)
private
FMyString: string;
FOnTest: TNotifyEvent;
protected
property MyString: string read FMyString write FMyString;
property OnTest: TNotifyEvent read FOnTest write FOnTest;
end;

TTestProperties = class(TCustomTestProperties)
published
property MyString;
property OnTest;
end;

TCustomTestEditor = class(TEdit)
private
FMyTestProperties: TTestProperties;
protected
property MyTestProperties: TTestProperties read FMyTestProperties write FMyTestProperties;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;

TTestEditor = class(TCustomTestEditor)
published
property MyTestProperties;
end;
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2017 11:20 AM   in response to: Brent Rose in response to: Brent Rose
Brent Rose wrote:

On the Object Inspector properties tab, my property class appears as
expected, with the defined sub-properties below it. However, the
events of the property class do not appear on the events tab at all.
Is there something more I need to do to publish the events? Thanks.

The Object Inspector is perfectly capable of displaying sub-property
published events just fine without requiring extra coding.

For example, assign a TPopupMenu to a Form or UI control, and then make
sure that Form/Control is focused and look at the Object Inspector. The
TPopupMenu's OnChange and OnPopup events should be visible in addition
to the Form/Control's own events. TPopupMenu doesn't have any special
code to accomplish that.

Here is some simplified code creating a "TTestEditor " derived from
TEdit which reproduces the problem as described

FYI, your test property is not setup correctly. It needs to have a
setter method that calls Assign() on your test object, and then you
need to override Assign() in the TCustomTestProperties class.

Otherwise, if anyone ever assigns a value to the property, you
erroneously take ownership of that pointer and leak your initial object.

Try this instead:

type
  TCustomTestProperties = class(TPersistent)
  private
    FMyString: string;
    FOnTest: TNotifyEvent;
  protected
    property MyString: string read FMyString write FMyString;
    property OnTest: TNotifyEvent read FOnTest write FOnTest;
  public
    procedure Assign(Source: TPersistent); override;
  end;
 
  TTestProperties = class(TCustomTestProperties)
  published
    property MyString;
    property OnTest;
  end;
 
  TCustomTestEditor = class(TEdit)
  private
    FMyTestProperties: TTestProperties;
    procedure SetMyTestProperties(AValue: TTestProperties);
  protected
    property MyTestProperties: TTestProperties read FMyTestProperties
write SetMyTestProperties;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;
 
  TTestEditor = class(TCustomTestEditor)
  published
    property MyTestProperties;
  end;
 
...
 
procedure TCustomTestProperties.Assign(Source: TPersistent);
begin
  if Source is TCustomTestProperties then
    FMyString := TCustomTestProperties(Source).MyString
  else
    inherited;
end;
 
constructor TCustomTestEditor.Create(AOwner: TComponent);
begin
  inherited;
  FMyTestProperties := TTestProperties.Create;
end;
 
destructor TCustomTestEditor.Destroy;
begin
  FMyTestProperties.Free;
  inherited;
end;
 
procedure TCustomTestEditor.SetMyTestProperties(AValue:
TTestProperties);
begin
  FMyTestProperties.Assign(AValue);
end;


--
Remy Lebeau (TeamB)
Brent Rose

Posts: 126
Registered: 9/23/00
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2017 8:41 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks Remy, I have applied your changes as suggested.

With the event, however, it is still not working. I am aware of the
PopupMenu example (and similar) that you describe - and that sort of
result is exactly what I want to achieve.

Specifically, in this case, I want to have the event "OnTest" appearing
as a sub-event under "MyTestProperties" on the Object Inspectors event
tab, just like the properties of same appear (successfully) on the
properties tab.

From the few hints I have been able to discover, it is actually
somewhat tricky implementing this... but I may be quite wrong So far, I
have not been able to find a working example demonstrating how it is
done. If I have not made another mistake with what I have already, maybe
I'll have to see if I can dissect something out of other components that
achieve the result...

On 21/12/2017 8:20 AM, Remy Lebeau (TeamB) wrote:
Brent Rose wrote:

On the Object Inspector properties tab, my property class appears as
expected, with the defined sub-properties below it. However, the
events of the property class do not appear on the events tab at all.
Is there something more I need to do to publish the events? Thanks.

The Object Inspector is perfectly capable of displaying sub-property
published events just fine without requiring extra coding.

For example, assign a TPopupMenu to a Form or UI control, and then make
sure that Form/Control is focused and look at the Object Inspector. The
TPopupMenu's OnChange and OnPopup events should be visible in addition
to the Form/Control's own events. TPopupMenu doesn't have any special
code to accomplish that.

Here is some simplified code creating a "TTestEditor " derived from
TEdit which reproduces the problem as described

FYI, your test property is not setup correctly. It needs to have a
setter method that calls Assign() on your test object, and then you
need to override Assign() in the TCustomTestProperties class.

Otherwise, if anyone ever assigns a value to the property, you
erroneously take ownership of that pointer and leak your initial object.

Try this instead:

type
   TCustomTestProperties = class(TPersistent)
   private
     FMyString: string;
     FOnTest: TNotifyEvent;
   protected
     property MyString: string read FMyString write FMyString;
     property OnTest: TNotifyEvent read FOnTest write FOnTest;
   public
     procedure Assign(Source: TPersistent); override;
   end;
 
   TTestProperties = class(TCustomTestProperties)
   published
     property MyString;
     property OnTest;
   end;
 
   TCustomTestEditor = class(TEdit)
   private
     FMyTestProperties: TTestProperties;
     procedure SetMyTestProperties(AValue: TTestProperties);
   protected
     property MyTestProperties: TTestProperties read FMyTestProperties
write SetMyTestProperties;
   public
     constructor Create(AOwner: TComponent); override;
     destructor Destroy; override;
   end;
 
   TTestEditor = class(TCustomTestEditor)
   published
     property MyTestProperties;
   end;
 
...
 
procedure TCustomTestProperties.Assign(Source: TPersistent);
begin
   if Source is TCustomTestProperties then
     FMyString := TCustomTestProperties(Source).MyString
   else
     inherited;
end;
 
constructor TCustomTestEditor.Create(AOwner: TComponent);
begin
   inherited;
   FMyTestProperties := TTestProperties.Create;
end;
 
destructor TCustomTestEditor.Destroy;
begin
   FMyTestProperties.Free;
   inherited;
end;
 
procedure TCustomTestEditor.SetMyTestProperties(AValue:
TTestProperties);
begin
   FMyTestProperties.Assign(AValue);
end;

--
Brent Rose

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2017 10:43 AM   in response to: Brent Rose in response to: Brent Rose
Brent Rose wrote:

Specifically, in this case, I want to have the event "OnTest"
appearing as a sub-event under "MyTestProperties" on the Object
Inspectors event tab, just like the properties of same appear
(successfully) on the properties tab.

From the few hints I have been able to discover, it is actually
somewhat tricky implementing this...

Custom Component Editors in Delphi - #2 - Sub-events and Sub-properties
http://edn.embarcadero.com/article/32956

It is a bit dated, but it might still be relevant.

--
Remy Lebeau (TeamB)
Brent Rose

Posts: 126
Registered: 9/23/00
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2017 12:26 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks Remy. Yes, I had already reviewed this article. Unfortunately,
the link to the sample code/project is no longer valid. I have not been
able to trace the original author (invalid links and contact details
etc) or any other source for the samples.

This link http://forum.lazarus.freepascal.org/index.php?topic=8725.0 may
have some useful information, being a derivation of the same missing
sample. There is a lot to it, so will have to see how I go...

On 22/12/2017 7:43 AM, Remy Lebeau (TeamB) wrote:

Brent Rose wrote:

Specifically, in this case, I want to have the event "OnTest"
appearing as a sub-event under "MyTestProperties" on the Object
Inspectors event tab, just like the properties of same appear
(successfully) on the properties tab.

From the few hints I have been able to discover, it is actually
somewhat tricky implementing this...

Custom Component Editors in Delphi - #2 - Sub-events and Sub-properties
http://edn.embarcadero.com/article/32956

It is a bit dated, but it might still be relevant.

--
Brent Rose

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2017 1:36 PM   in response to: Brent Rose in response to: Brent Rose
Brent Rose wrote:

This link http://forum.lazarus.freepascal.org/index.php?topic=8725.0
may have some useful information, being a derivation of the same
missing sample. There is a lot to it, so will have to see how I go...

I have to ask - why do you need this functionality in the first place?
Why can't your main component expose all of the necessary events?

--
Remy Lebeau (TeamB)
Brent Rose

Posts: 126
Registered: 9/23/00
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2017 2:11 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Good question. Simple answer is yes, my component could simply expose
the events (and that is what I will have to do if I cannot get them
successfully grouped under a separate "header").

However, I am adding quite a few extra properties and events in the
component descendant, so it makes a lot of sense to have mine separately
grouped for convenience.

This works really well for the properties, I had just not anticipated it
would be such a problem getting the same for the events.

On 22/12/2017 10:36 AM, Remy Lebeau (TeamB) wrote:
Brent Rose wrote:

This link http://forum.lazarus.freepascal.org/index.php?topic=8725.0
may have some useful information, being a derivation of the same
missing sample. There is a lot to it, so will have to see how I go...

I have to ask - why do you need this functionality in the first place?
Why can't your main component expose all of the necessary events?

--
Brent Rose

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2017 4:08 PM   in response to: Brent Rose in response to: Brent Rose
Brent Rose wrote:

Good question. Simple answer is yes, my component could simply expose
the events (and that is what I will have to do if I cannot get them
successfully grouped under a separate "header").

However, I am adding quite a few extra properties and events in the
component descendant, so it makes a lot of sense to have mine
separately grouped for convenience.

This works really well for the properties, I had just not anticipated
it would be such a problem getting the same for the events.

The sample code for the earlier EDN article
(http://edn.embarcadero.com/article/32956) is still available on
CodeCentral, the link in the article is broken (since it points at
Borland instead of Embarcadero), here is the working link:

https://cc.embarcadero.com/Item.aspx?id=23113

It's pretty ugly code for something that should logically be simple,
though.

--
Remy Lebeau (TeamB)
Brent Rose

Posts: 126
Registered: 9/23/00
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2017 7:22 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks Remy - appreciate your follow up on this.

I agree with your assessment: it is very ugly. I'll stick with ungrouped
events, I think ;-) It is not worth the trouble for one component.

As you suggest, it does beg the question why sub-events are not
published like sub-properties as a standard part of the IDE... seems
like a reasonable thing to expect. Have created an Issue for it...

On 22/12/2017 1:08 PM, Remy Lebeau (TeamB) wrote:
Brent Rose wrote:

Good question. Simple answer is yes, my component could simply expose
the events (and that is what I will have to do if I cannot get them
successfully grouped under a separate "header").

However, I am adding quite a few extra properties and events in the
component descendant, so it makes a lot of sense to have mine
separately grouped for convenience.

This works really well for the properties, I had just not anticipated
it would be such a problem getting the same for the events.

The sample code for the earlier EDN article
(http://edn.embarcadero.com/article/32956) is still available on
CodeCentral, the link in the article is broken (since it points at
Borland instead of Embarcadero), here is the working link:

https://cc.embarcadero.com/Item.aspx?id=23113

It's pretty ugly code for something that should logically be simple,
though.

--
Brent Rose

Brandon Staggs

Posts: 683
Registered: 3/3/01
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2017 6:05 AM   in response to: Brent Rose in response to: Brent Rose
I have this working in one of my own custom components. Unless I am
missing something about your needs, it is not that hard to do. Two
important things must be done:

1. Give the subcomponent a proper name when the parent component
creates it.

2. Call SetSubComponent(True).

Example I copy and pasted from a component I made a few months ago:

FViewer := TslViewer.Create(Self);
FViewer.SetSubComponent(True);
FViewer.Name := 'SubViewer';
FViewer.Parent := Self;

During design time, the sub-object properties are published in the IDE
and can be changed/saved/etc. Works for me...

That said, I see Remy posted a lot for you. He knows his stuff. I am
left thinking I must have missed something.

--
Brandon Staggs
StudyLamp Software LLC
http://www.studylamp.com
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2017 11:52 AM   in response to: Brandon Staggs in response to: Brandon Staggs
Brandon Staggs wrote:

1. Give the subcomponent a proper name when the parent component
creates it.

2. Call SetSubComponent(True).

That only applies to sub-properties that are implemented as a class
derived from TComponent, not TPersistent directly.

--
Remy Lebeau (TeamB)
Brandon Staggs

Posts: 683
Registered: 3/3/01
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2017 5:21 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
"Remy Lebeau" wrote on Fri, 22 Dec 2017 11:52:57 -0800:

That only applies to sub-properties that are implemented as a class
derived from TComponent, not TPersistent directly.

I knew I was missing something. :-)

--
Brandon Staggs
StudyLamp Software LLC
http://www.studylamp.com
Brent Rose

Posts: 126
Registered: 9/23/00
Re: How to publish sub-events in a component  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2017 4:03 PM   in response to: Brandon Staggs in response to: Brandon Staggs
Thanks for your suggestion here, Brandon. Not quite what I need (as Remy
has replied), but appreciated.

On 23/12/2017 3:05 AM, Brandon Staggs wrote:
I have this working in one of my own custom components. Unless I am
missing something about your needs, it is not that hard to do. Two
important things must be done:

1. Give the subcomponent a proper name when the parent component
creates it.

2. Call SetSubComponent(True).

Example I copy and pasted from a component I made a few months ago:

FViewer := TslViewer.Create(Self);
FViewer.SetSubComponent(True);
FViewer.Name := 'SubViewer';
FViewer.Parent := Self;

During design time, the sub-object properties are published in the IDE
and can be changed/saved/etc. Works for me...

That said, I see Remy posted a lot for you. He knows his stuff. I am
left thinking I must have missed something.

--
Brent Rose

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02