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 InitialiseComponent() method to set the new
forecolour.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
'
'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 InitialiseComponent() which totally negates
the inheritance - I find this in the form's InitialiseComponent().
'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 InitialiseComponent() 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 InitialiseComponent() 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 InitialiseComponent()
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 11 2146
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 InitialiseComponent() in the form's
InitialiseComponent() - 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 InitialiseComponent() method to set the new forecolour. <System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent() ' '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 InitialiseComponent() which totally
negates the inheritance - I find this in the form's InitialiseComponent().
'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 InitialiseComponent() 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 InitialiseComponent() 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 InitialiseComponent()
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
"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
> 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.
"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.equals(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.ComponentModel.DefaultValue(GetType(Color) , "Red")> _
Public Overloads Property ForeColor() As Color
Get
Return MyBase.ForeColor
End Get
Set(ByVal Value As Color)
MyBase.ForeColor = 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
Thanks for sticking with me on this, Armin.
<System.ComponentModel.DefaultValue(GetType(Color) , "Red")> _
Public Overloads Property ForeColor() As Color
Get
Return MyBase.ForeColor
End Get
Set(ByVal Value As Color)
MyBase.ForeColor = Value
End Set
End Property
Ouch !!
That's incredibly complex!
I was hoping this would work:
Function ShouldSerializeForeColor() As Boolean
ShouldSerializeForeColor = 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 ShouldSerializeText()
{
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.
> if not c.forecolor.equals(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
InitializeComponent().
Logically it's doing something like this (if parentclass was a property of a
control subclass) in the designer.
if not c.corefolor.equals(c.parentclass.forecolor) then
' write following code to the form InitializeComponent()
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.
"PAul Maskens" <pm******@mvps.org> schrieb Thanks for sticking with me on this, Armin.
<System.ComponentModel.DefaultValue(GetType(Color) , "Red")> _ Public Overloads Property ForeColor() As Color
This should have been
public OVERRIDES property....
Get Return MyBase.ForeColor End Get Set(ByVal Value As Color) MyBase.ForeColor = 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 ShouldSerializeForeColor() As Boolean ShouldSerializeForeColor = 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 ShouldSerializeText() { 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 ShouldSerializeForeColor() As Boolean
Return (Not Me.ForeColor.Equals(Color.Red))
End Function
But, _in addition_ you have to override the ForeColor property:
Public Overrides Property ForeColor() As Color
Get
Return MyBase.ForeColor
End Get
Set(ByVal Value As Color)
MyBase.ForeColor = 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.ShouldSerializeForeColor. To change this behavior, you have to
override the property. Consequently the designer looks for
ShouldSerializeForeColor in your derived class.
--
Armin
"PAul Maskens" <pm******@mvps.org> schrieb if not c.forecolor.equals(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 InitializeComponent(). Logically it's doing something like this (if parentclass was a property of a control subclass) in the designer.
if not c.corefolor.equals(c.parentclass.forecolor) then ' write following code to the form InitializeComponent() 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 DefaultValueAttribute. 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
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 ShouldSerializeForeColor() As Boolean
ShouldSerializeForeColor = 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 ShouldSerializeText()
{
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.
"PAul Maskens" <pm******@mvps.org> schrieb Do you have any idea why the ShouldSerialize<property>() method isn't working? Can you see any mistake in what I tried in VB?
It works for me. See my answer to your other message.
Function ShouldSerializeForeColor() As Boolean ShouldSerializeForeColor = false End Function
I would not always set it to false. If you change the Color to Green within
the designer, the setting won't be stored.
--
Armin
That's fine.
We don't want colour changes to be made in the designer.
We are using an ObjectMode proeprty which says what kind of control it is
(in our application) and that drives the setting of appropriate colours
depending on control and application state.
Yes, we're ignoring windows standards, which I don't think is such a good
thing.
But it emulates an existing application's UI.
We planned to do this in a root class layer, inheriting directly from the
base controls, so that we could apply comany-wide standards there. Then
lower layers can add application specializations if necessary.
Designer support for this is critical, so we can reissue the libraries
separately from the application. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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
...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
|
by: WisdomUfot |
last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
|
by: Oralloy |
last post by:
Hello Folks,
I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA.
My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
|
by: BLUEPANDA |
last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
|
by: Ricardo de Mila |
last post by:
Dear people, good afternoon...
I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control.
Than I need to discover what...
|
by: Johno34 |
last post by:
I have this click event on my form. It speaks to a Datasheet Subform
Private Sub Command260_Click()
Dim r As DAO.Recordset
Set r = Form_frmABCD.Form.RecordsetClone
r.MoveFirst
Do
If...
|
by: DizelArs |
last post by:
Hi all)
Faced with a problem, element.click() event doesn't work in Safari browser.
Tried various tricks like emulating touch event through a function:
let clickEvent = new Event('click', {...
| |