473,837 Members | 1,501 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Control inheritance spoiled by Form designer.

The form designer adds unnecessary code to the section when using a
subclassed control.
I've reproduced this in VS.NET 2002 and VS.NET 2003 so it's pretty
fundamental.

Outline steps:
Create a VB project.
Create a subclass of a UI control, I used TextBox.
Add no code to the subclass.
Public Class Component1
Inherits System.Windows. Forms.TextBox
#Region " Component Designer generated code "
#End Region
End Class

Change the forecolour property only (Red in this example).
The designer adds code to the InitialiseCompo nent() method to set the new
forecolour.
<System.Diagnos tics.DebuggerSt epThrough()> Private Sub InitializeCompo nent()
'
'Component1
'
Me.ForeColor = System.Drawing. Color.Red
End Sub

Build it.

Create a VB windows form project.
Drag/drop a baseclass textbox.
Add reference to the DLL containing the control.
Add that to the toolbox.
Drag/drop a subclassed textbox.

All appears good.
But looking at the code it's not using inheritance !!

The form designer incorrectly (IMO) adds a line of code which duplicates the
code in the subclassed control's InitialiseCompo nent() which totally negates
the inheritance - I find this in the form's InitialiseCompo nent().

'Component11
'
Me.Component11. ForeColor = System.Drawing. Color.Red

If I distribute the control subclass as a separate assembly (dll) and then
update that dll, the compiled form has code that is hardwired to set the
colour of the instance of the control.
That's not right!
Because when I distribute a new version of the control with a different
forecolour, the code in the contorl's InitialiseCompo nent() might just as
well not be there - because the VB form has a line of code to set the colour
to that of the version of the component used at the time the form was
edited.
I can remove the offending code from the form's InitialiseCompo nent() and it
has no visual effect.
The colour is still as defined in the subclassed control.
I can change the control's forecolour, rebuild the dll and the form shows
the new forecolour.
There is still no offending code in the form InitialiseCompo nent()

Now we enter the twilight zone ...
In the form designer, if I move _either_ of the two textboxes, the offending
line of code reappears.
So, is this a known bug?
I don't want to have to put code in the subclassed control's Paint() method
for example, because that gets called far too often.

--

PAul
Nov 20 '05 #1
11 2275
I've now reproduced this in a C# form too, using the same VB subclass of
textbox, so it's pretty fundamental!

There is no reason as far as I can see that the form should have a copy of
the code from the subclasses control's InitialiseCompo nent() in the form's
InitialiseCompo nent() - because that overrides any change you may make in
the control class.
The form designer adds unnecessary code to the section when using a
subclassed control.
I've reproduced this in VS.NET 2002 and VS.NET 2003 so it's pretty
fundamental.

Outline steps:
Create a VB project.
Create a subclass of a UI control, I used TextBox.
Add no code to the subclass.
Public Class Component1
Inherits System.Windows. Forms.TextBox
#Region " Component Designer generated code "
#End Region
End Class

Change the forecolour property only (Red in this example).
The designer adds code to the InitialiseCompo nent() method to set the new
forecolour.
<System.Diagnos tics.DebuggerSt epThrough()> Private Sub InitializeCompo nent() '
'Component1
'
Me.ForeColor = System.Drawing. Color.Red
End Sub

Build it.

Create a VB windows form project.
Drag/drop a baseclass textbox.
Add reference to the DLL containing the control.
Add that to the toolbox.
Drag/drop a subclassed textbox.

All appears good.
But looking at the code it's not using inheritance !!

The form designer incorrectly (IMO) adds a line of code which duplicates the code in the subclassed control's InitialiseCompo nent() which totally negates the inheritance - I find this in the form's InitialiseCompo nent().

'Component11
'
Me.Component11. ForeColor = System.Drawing. Color.Red

If I distribute the control subclass as a separate assembly (dll) and then
update that dll, the compiled form has code that is hardwired to set the
colour of the instance of the control.
That's not right!
Because when I distribute a new version of the control with a different
forecolour, the code in the contorl's InitialiseCompo nent() might just as
well not be there - because the VB form has a line of code to set the colour to that of the version of the component used at the time the form was
edited.
I can remove the offending code from the form's InitialiseCompo nent() and it has no visual effect.
The colour is still as defined in the subclassed control.
I can change the control's forecolour, rebuild the dll and the form shows
the new forecolour.
There is still no offending code in the form InitialiseCompo nent()

Now we enter the twilight zone ...
In the form designer, if I move _either_ of the two textboxes, the offending line of code reappears.
So, is this a known bug?
I don't want to have to put code in the subclassed control's Paint() method for example, because that gets called far too often.

--

PAul

Nov 20 '05 #2
"PAul Maskens" <pm******@mvps. org> schrieb
The form designer adds unnecessary code to the section when using
a subclassed control.
I've reproduced this in VS.NET 2002 and VS.NET 2003 so it's pretty
fundamental.
[...]


It is not an inheritance issue. The designer is not interested in the
inheritance hierarchy. The reason why it creates the code is that the
property value (red) is not equal to default value of the property.

See also (didn't read the whole article):
http://msdn.microsoft.com/library/en...ustcodegen.asp

quote: "...If the current value of a property matches that default value,
code is not generated."

--
Armin

How to quote and why:
http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html

Nov 20 '05 #3
> It is not an inheritance issue.
Becauase it prevents us using inheritance to define visual characteristics ,
and redefine in a new release of the assembly containing the subclass, it is
an inheritance issue.
The designer is not interested in the inheritance hierarchy. Exactly, so the designer is breaking inheritcance.
The reason why it creates the code is that the property value (red)
is not equal to default value of the property. What were they smoking when they designed that, then?
quote: "...If the current value of a property matches that default value,
code is not generated."

So the question then is, how do I define the new value in my subclass as the
new default?

It's not a show stopper, but I've been using OO languages for ten years and
this is unbelievable.
Nov 20 '05 #4
"PAul Maskens" <pm******@mvps. org> schrieb
It is not an inheritance issue. Becauase it prevents us using inheritance to define visual
characteristics , and redefine in a new release of the assembly
containing the subclass, it is an inheritance issue.
The designer is not interested in the inheritance hierarchy.

Exactly, so the designer is breaking inheritcance.


The designer creates code. Neither it changes your controls nor derives new
controls from yours, consequently it is impossible that it brakes
inheritance.
The reason why it creates the code is that the property value
(red) is not equal to default value of the property.

What were they smoking when they designed that, then?


Why? How can the designer know that the constructor of your control already
sets the value? It would have to analyse the source code or your control.
Not possible. Or, it would have to create the following code:

if not c.forecolor.equ als(color.red) then
c.forecolor = color.red
end if

Wouldn't make sense, too, as we both know.
quote: "...If the current value of a property matches that default
value, code is not generated."

So the question then is, how do I define the new value in my subclass
as the new default?


As mentioned in the linked article, there's the DefaultValue attribute:

<System.Compone ntModel.Default Value(GetType(C olor), "Red")> _
Public Overloads Property ForeColor() As Color
Get
Return MyBase.ForeColo r
End Get
Set(ByVal Value As Color)
MyBase.ForeColo r = Value
End Set
End Property

Seems to work.

It's not a show stopper, but I've been using OO languages for ten
years and this is unbelievable.


IMO it is not related to OO and especially inheritance at all.
--
Armin

Nov 20 '05 #5
Thanks for sticking with me on this, Armin.

<System.Compone ntModel.Default Value(GetType(C olor), "Red")> _
Public Overloads Property ForeColor() As Color
Get
Return MyBase.ForeColo r
End Get
Set(ByVal Value As Color)
MyBase.ForeColo r = Value
End Set
End Property

Ouch !!
That's incredibly complex!
I was hoping this would work:

Function ShouldSerialize ForeColor() As Boolean
ShouldSerialize ForeColor = false
End Function

Like the C# example in the article.

Quote:
But what if the default value is not a simple one or this needs to be done more dynamically? This is often the case for values that are inherited from other components such as a parent Control. The dynamic case can be handled by adding a method of a certain signature. Using the example above, the code would look like this:

private bool ShouldSerialize Text()
{
return Text != "OK";
}
By adding a method of the name ShouldSerialize <Property Name>, the code generation engine can ask the component if it would like the value to be serialized.
I can't get that to work in my simple test.
So I'm doing something wrong.
Nov 20 '05 #6
> if not c.forecolor.equ als(color.red) then
c.forecolor = color.red
end if Why does the designer effectively do just that?
True, in this case it's analysing the value of the property.

What it does is if the current colour of my control subclass is not the
default colour of the parentclass, it writes a line of code into the form's
InitializeCompo nent().
Logically it's doing something like this (if parentclass was a property of a
control subclass) in the designer.

if not c.corefolor.equ als(c.parentcla ss.forecolor) then
' write following code to the form InitializeCompo nent()
me.c.foreColor = color.green
end if

It would have to analyse the source code or your control.

In this case it's analysing the property values.
Nov 20 '05 #7
"PAul Maskens" <pm******@mvps. org> schrieb
Thanks for sticking with me on this, Armin.

<System.Compone ntModel.Default Value(GetType(C olor), "Red")> _
Public Overloads Property ForeColor() As Color
This should have been

public OVERRIDES property....
Get
Return MyBase.ForeColo r
End Get
Set(ByVal Value As Color)
MyBase.ForeColo r = Value
End Set
End Property

Ouch !!
That's incredibly complex!
Well, attaching an attribute is not complex, but you can not attach an
attribute to a derived member, so you have to override it to get a procedure
to attach an attribute to.
I was hoping this would work:

Function ShouldSerialize ForeColor() As Boolean
ShouldSerialize ForeColor = false
End Function

Like the C# example in the article.

Quote:
But what if the default value is not a simple one or this needs to be
done more dynamically? This is often the case for values that are
inherited from other components such as a parent Control. The dynamic
case can be handled by adding a method of a certain signature. Using
the example above, the code would look like this:

private bool ShouldSerialize Text()
{
return Text != "OK";
}
By adding a method of the name ShouldSerialize <Property Name>, the
code generation engine can ask the component if it would like the
value to be serialized.


I learn many new things in this thread. :-) This works for me:

Private Function ShouldSerialize ForeColor() As Boolean
Return (Not Me.ForeColor.Eq uals(Color.Red) )
End Function

But, _in addition_ you have to override the ForeColor property:

Public Overrides Property ForeColor() As Color
Get
Return MyBase.ForeColo r
End Get
Set(ByVal Value As Color)
MyBase.ForeColo r = Value
End Set
End Property
Why? The ForeColor property is part of the TextBoxBase class. The designer
looks at the members of the same type that contains the property to be
serialized to find the ShouldSerialize * function. It does find it, but it's
derived from the Control class. So, the designer calls
Control.ShouldS erializeForeCol or. To change this behavior, you have to
override the property. Consequently the designer looks for
ShouldSerialize ForeColor in your derived class.

--
Armin

Nov 20 '05 #8
"PAul Maskens" <pm******@mvps. org> schrieb
if not c.forecolor.equ als(color.red) then
c.forecolor = color.red
end if Why does the designer effectively do just that?


It does *not* create this code. I wrote "it would have to create...".
True, in this case it's analysing the value of the property.

What it does is if the current colour of my control subclass is not
the default colour of the parentclass, it writes a line of code into
the form's InitializeCompo nent().
Logically it's doing something like this (if parentclass was a
property of a control subclass) in the designer.

if not c.corefolor.equ als(c.parentcla ss.forecolor) then
' write following code to the form InitializeCompo nent()
me.c.foreColor = color.green
end if


What is a corefolor? ;-)) Anyway, I currently can not follow you. I wanted
to say that the designer compares the forecolor to the color specified in
the DefaultValueAtt ribute. If not equal => code is generated.
It would have to analyse the source code or your control.

In this case it's analysing the property values.


I'm not sure if I understand you. What I'm trying to say is that the
designer does not know if you already set Forecolor = Red within the
constructor. Consequently the designer must generate the code that you don't
want to be created.
--
Armin

Nov 20 '05 #9
Do you have any idea why the ShouldSerialize <property>() method isn't
working?
Can you see any mistake in what I tried in VB?

Function ShouldSerialize ForeColor() As Boolean
ShouldSerialize ForeColor = false
End Function
I am trying to use this approach. Because it talks exactly about what we are
doing, with a value inherited from a parent control.
Quote:
But what if the default value is not a simple one or this needs to be done
more dynamically? This is often the case for values that are inherited from
other components such as a parent Control. The dynamic case can be handled
by adding a method of a certain signature. Using the example above, the code
would look like this:

private bool ShouldSerialize Text()
{
return Text != "OK";
}
By adding a method of the name ShouldSerialize <Property Name>, the code
generation engine can ask the component if it would like the value to be
serialized.
Nov 20 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
8016
by: Jason Hickey | last post by:
Has there been a change in the way the UI designer handles winform inheritance in the 2003 version of visual studio. Consider the following (try it if you are using 2003 Everything seems to work under 2002) Create a form and add two buttons (bottom right) and a panel (fill the top of the form) Anchor the buttons to the bottom right and anchor the panel to top bottom left and right. set all three controls access level to protected
1
6807
by: tjmii | last post by:
I'm trying to use several web user controls on a page that share some common functionality. So, I want the user controls to inherit from a base class. I started off making this simple base class Public Class BaseClass : Inherits System.Web.UI.UserControl Public Property TableWidth as Integer Get Return baseTable.Width End Get Set (ByVal Value As Integer)
1
6293
by: Reza Nabi | last post by:
Bakground: I have a webform (LoadCtl.aspx) which loads the user control to a placeholder dynamically based on the ctlName querystring passed in the URL. Webform (LoadCtl.aspx) also passes a variable (targetId) in to the usercontrol (IntergySite.aspx) by calling its setter method. Currently, I am using if-then-else and hardcoded the User Control Object to do casting and call the setter method. Question: Is there any way I could load,...
2
1880
by: Mark | last post by:
I have basically a 2 part question: 1) is there a way to have a listview that can scroll, but hide the scrollbars. I know that sounds odd, but this is a touch screen app and there are "scroll buttons (just command buttons with graphic)" that go to the next/previous item in the list and that allows the scrolling. I know they can drag the scroll bar down by touching, but that causes me a problem when the selected item goes out of view...
2
2196
by: Ray Cassick \(Home\) | last post by:
Since I got such good feedback from the Xml comments question I will ask this of the group as well. Is VS.NET 2005 handling the visual inheritance problems centered around controls and forms that are decorated with MustInherit any better than 2003 did? I am getting really tired of having to do the good old '#If DEBUG Then' workaround just to get by this.
0
1137
by: Marc Gravell | last post by:
Is there any (good) way to stop the designer trying to load a specific form/control when I double-click it in the solution explorer? Basically, I have some controls that either use generics or are base (inheritance) forms best viewed in the code view. I looked at the attributes in System.ComponentModel, but couldn't find much that helps... I can add the following before my control declaration, which successfully stops the designer...
0
1470
by: fds | last post by:
Hello! I have a very specific question and that is about how to inherit a control for example the control System.Windows.Forms.TextBox without causing the environment to delete the control when there are some compile errors. It's the same problem with any visual control that you inherit. The control is deleted as soon as you use the View Designer when there is compile error. It's very easy to reproduce my problem. You can do it in...
0
1599
by: Tony Johansson | last post by:
Hello! I have a very specific question and that is about how to inherit a visual control for example the control System.Windows.Forms.TextBox without causing the environment to delete the control when there are some compile errors. It's the same problem with any visual control that you inherit. The control is deleted as soon as you use the View Designer when there is compile error. It's very easy to reproduce my problem. You can do...
4
4368
by: iKiLL | last post by:
Hi All I am Developing in C# with VS2005. I am Developing a Windows Mobile Forms Application with the CF2 My problem is that when the Input panel is displayed my screen does not
0
9835
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10870
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10617
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10265
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9391
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5667
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5843
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4469
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4036
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.