BlackMan
asked on
Setting properties on new components
My problems is about setting componentproperties as runtime.
I have made 2 test components to show my problem, TMyEdit and TMyGroupBox.
TMyEdit.Enable will (in this test) set its background to red.
MyGroupBox.Enable will iterate all components in it and set the Enable property on them.
Here are snips from my code:
TMyEdit = class(TEdit)
private
Function GetEnabled: Boolean;
Procedure SetEnabled(ABoolean: Boolean);
protected
public
published
Property Enabled: Boolean Read GetEnabled Write SetEnabled;
end;
Function TMyEdit.GetEnabled: Boolean;
begin
Result := Inherited Enabled;
end;
Procedure TMyEdit.SetEnabled(ABoolea n: Boolean);
begin
if ABoolean <> Enabled then
begin
if ABoolean then
Color := clWindow
else
Color := clRed;
Inherited Enabled := ABoolean;
end;
end;
TMyGroupBox = class(TGroupBox)
private
Function GetEnabled: Boolean;
Procedure SetEnabled(ABoolean: Boolean);
protected
public
published
Property Enabled: Boolean Read GetEnabled Write SetEnabled;
end;
Function TMyGroupBox.GetEnabled: Boolean;
begin
Result := Inherited Enabled;
end;
Procedure TMyGroupBox.SetEnabled(ABo olean: Boolean);
Var
i: Integer;
begin
if ABoolean <> Enabled then
begin
for i := 0 to ControlCount-1 do
Controls[i].Enabled := ABoolean;
Inherited Enabled := ABoolean;
end;
end;
What I do is that I put a MyGroupBox on a form and drops a MyEdit in it. Now, if I at runtime change the Enabled value of MyEdit, the background will change accordingly.
If I change Enabled for MyGroupBox, it will not call (Set)Enabled for MyEdit but instead it calls it on TEdit (the parent component).
Now, if I change the For loop to read
for i := 0 to ControlCount-1 do
if (Controls[i] is TMyListBox) then
(Controls[i] As TMyListBox).Enabled := ABoolean
else
Controls[i].Enabled := ABoolean;
it will work. But I don't want MyGroupBox to know all possible components that I will drop in it.
Anyone has a clue?
I have made 2 test components to show my problem, TMyEdit and TMyGroupBox.
TMyEdit.Enable will (in this test) set its background to red.
MyGroupBox.Enable will iterate all components in it and set the Enable property on them.
Here are snips from my code:
TMyEdit = class(TEdit)
private
Function GetEnabled: Boolean;
Procedure SetEnabled(ABoolean: Boolean);
protected
public
published
Property Enabled: Boolean Read GetEnabled Write SetEnabled;
end;
Function TMyEdit.GetEnabled: Boolean;
begin
Result := Inherited Enabled;
end;
Procedure TMyEdit.SetEnabled(ABoolea
begin
if ABoolean <> Enabled then
begin
if ABoolean then
Color := clWindow
else
Color := clRed;
Inherited Enabled := ABoolean;
end;
end;
TMyGroupBox = class(TGroupBox)
private
Function GetEnabled: Boolean;
Procedure SetEnabled(ABoolean: Boolean);
protected
public
published
Property Enabled: Boolean Read GetEnabled Write SetEnabled;
end;
Function TMyGroupBox.GetEnabled: Boolean;
begin
Result := Inherited Enabled;
end;
Procedure TMyGroupBox.SetEnabled(ABo
Var
i: Integer;
begin
if ABoolean <> Enabled then
begin
for i := 0 to ControlCount-1 do
Controls[i].Enabled := ABoolean;
Inherited Enabled := ABoolean;
end;
end;
What I do is that I put a MyGroupBox on a form and drops a MyEdit in it. Now, if I at runtime change the Enabled value of MyEdit, the background will change accordingly.
If I change Enabled for MyGroupBox, it will not call (Set)Enabled for MyEdit but instead it calls it on TEdit (the parent component).
Now, if I change the For loop to read
for i := 0 to ControlCount-1 do
if (Controls[i] is TMyListBox) then
(Controls[i] As TMyListBox).Enabled := ABoolean
else
Controls[i].Enabled := ABoolean;
it will work. But I don't want MyGroupBox to know all possible components that I will drop in it.
Anyone has a clue?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That one works, but can you explain why MyEdit.Enabled is not called in my component?
ASKER
Oops, I was to quick to send the other comment :-)
Your code works fine for Enabled but what if it was another property, like one I made myself?
Your code works fine for Enabled but what if it was another property, like one I made myself?
The problem is that GetEnabled and SetEnabled in TControl is not virtual.
If it were virtual you simple override it and all.
Suppose exists two class
type
TClass1 = class
public
procedure Print;
end;
TClass2 = class(TClass1)
public
procedure Print;
end;
procedure TClass1.Print;
begin
// print 'Class 111'
end;
procedure TClass2.Print;
begin
// print 'Class 222'
end;
and procedure ..
procedure Test(C: TClass1);
begin
C.Print;
end;
and you have two variables
var C1: TClass1;
C2: TClass2;
C1 := TClass1.Create; // Type of C1 is Class1
C2 := TClass2.Create; // Type of C2 is Class2
if you call Test(C1) you see 'Class 111'
if you call Test(C2) you as well as see 'Class 111' becouse Print is not virtual
if Print was virtual you see in first case 'Class 111' and 'Class 222' in second case
It is reason.
So, Delphi does not allow you override property Enabled but
notify you about its changing.
If it was another property and Get/Set not virtual and no notify message
I am afraid it is impossible
So, If you write components yourself make Get/Set protected and virtual.
If it were virtual you simple override it and all.
Suppose exists two class
type
TClass1 = class
public
procedure Print;
end;
TClass2 = class(TClass1)
public
procedure Print;
end;
procedure TClass1.Print;
begin
// print 'Class 111'
end;
procedure TClass2.Print;
begin
// print 'Class 222'
end;
and procedure ..
procedure Test(C: TClass1);
begin
C.Print;
end;
and you have two variables
var C1: TClass1;
C2: TClass2;
C1 := TClass1.Create; // Type of C1 is Class1
C2 := TClass2.Create; // Type of C2 is Class2
if you call Test(C1) you see 'Class 111'
if you call Test(C2) you as well as see 'Class 111' becouse Print is not virtual
if Print was virtual you see in first case 'Class 111' and 'Class 222' in second case
It is reason.
So, Delphi does not allow you override property Enabled but
notify you about its changing.
If it was another property and Get/Set not virtual and no notify message
I am afraid it is impossible
So, If you write components yourself make Get/Set protected and virtual.
ASKER
Thanks
ASKER