Control arrays and FormN.Label31

  • Thread starter Thread starter C
  • Start date Start date
C

C

VB Express 2008 converts VB6 code with control arrays fine and it
seems to work, but I cannot figure out what exactly it is doing. There
is some VB6.Compatibility functionality. I have plenty of arrays of
text boxes and labels on several forms.

Another problem is that I cannot address Label31 on each Form by a
subroutine in a module by FormN.Label31. What is good way around this?

Thanks.
 
Hello C,
Another problem is that I cannot address Label31 on each Form by a
subroutine in a module by FormN.Label31. What is good way around this?

you might want to check the modifier for that label.
If it is set to Private, you can't access it from outside.
the form.

Best regards,

Martin H.
 
VB Express 2008 converts VB6 code with control arrays fine and it
seems to work, but I cannot figure out what exactly it is doing. There
is some VB6.Compatibility functionality. I have plenty of arrays of
text boxes and labels on several forms.

It's doing the same thing that VB6 was doing, it's just more upfront
about it it -- it's creating a series of objects and adding them to a
array.

Unlike with VB6, these objects are directly addressable, so if you're
using constants for the array index you should just skip the array and
go directly to the back end object -- it'll have a name (that you can
change to be more re-memorable) and doing that makes your code more
understandable.

You might also look at iterating over the controls in containers
(panels, tabs and so forth), this might be related to what you're doing
with control arrays.
 
It's doing the same thing that VB6 was doing, it's just more upfront
about it it -- it's creating a series of objects and adding them to a
array.

Where do I find that code?
Unlike with VB6, these objects are directly addressable, so if you're
using constants for the array index you should just skip the array and
go directly to the back end object -- it'll have a name (that you can
change to be more re-memorable) and doing that makes your code more
understandable.

Probably not because I have lots of arrays for mathematical or
engineering calculations and sometimes some of those arrays have to be
displayed, or the user.has to be allowed to feed in the values of some
of those arrays.

There are also a couple of matrices which need to be shown, but
instead of using the grid, I have used a textbox array for years, with
textbox locations rearranged every time.
You might also look at iterating over the controls in containers
(panels, tabs and so forth), this might be related to what you're doing
with control arrays.

What is this for?

Thanks.
 
Hello C,


you might want to check the modifier for that label.
If it is set to Private, you can't access it from outside.
the form.

Best regards,

Martin H.

Its modifier is Public. Automatic conversion has done this.

Here is that subroutine:

Sub formsize(ByRef FormN As System.Windows.Forms.Form)

'UPGRADE_ISSUE: Form property FormN.ScaleWidth was not upgraded.
Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?
keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'
' FormN.ScaleWidth = 11940
FormN.Height = VB6.TwipsToPixelsY(8500)
FormN.Width = VB6.TwipsToPixelsX(12060)
FormN.BackColor = System.Drawing.ColorTranslator.FromOle(RGB(rrr,
ggg, bbb))
'UPGRADE_ISSUE: Form property FormN.DrawWidth was not upgraded.
Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?
keyword="CC4C7EC0-C903-48FC-ACCC-81861D12DA4A"'
' FormN.DrawWidth = 1
'UPGRADE_ISSUE: Control Label30 could not be resolved because it was
within the generic namespace Form. Click for more: 'ms-help://
MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="084D22AD-ECB1-400F-
B4C7-418ECEC5E36E"'
' FormN.Label30.Width = 8000
'UPGRADE_ISSUE: Control Label31 could not be resolved because it was
within the generic namespace Form. Click for more: 'ms-help://
MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="084D22AD-ECB1-400F-
B4C7-418ECEC5E36E"'
' FormN.Label31.Width = 8000
'UPGRADE_ISSUE: Control Label30 could not be resolved because it was
within the generic namespace Form. Click for more: 'ms-help://
MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="084D22AD-ECB1-400F-
B4C7-418ECEC5E36E"'
' FormN.Label30 = TitleS
'UPGRADE_ISSUE: Control Label31 could not be resolved because it was
within the generic namespace Form. Click for more: 'ms-help://
MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="084D22AD-ECB1-400F-
B4C7-418ECEC5E36E"'
' FormN.Label31 = SubtitleS
'UPGRADE_ISSUE: Control Label30 could not be resolved because it was
within the generic namespace Form. Click for more: 'ms-help://
MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="084D22AD-ECB1-400F-
B4C7-418ECEC5E36E"'
' FormN.Label30.ForeColor = RGB(r3, g3, b3)
'UPGRADE_ISSUE: Control Label31 could not be resolved because it was
within the generic namespace Form. Click for more: 'ms-help://
MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="084D22AD-ECB1-400F-
B4C7-418ECEC5E36E"'
' FormN.Label31.ForeColor = RGB(255, 255, 255)
If rrr = 255 And ggg = 255 And bbb = 255 Then
'UPGRADE_ISSUE: Control Label31 could not be resolved because it
was within the generic namespace Form. Click for more: 'ms-help://
MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="084D22AD-ECB1-400F-
B4C7-418ECEC5E36E"'
' FormN.Label31.ForeColor = RGB(0, 0, 0)
End If

End Sub
 
Its modifier is Public. Automatic conversion has done this.

Here is that subroutine:

Sub formsize(ByRef FormN As System.Windows.Forms.Form)

Two things, you don't need the ByRef and although it's not hurting
anything in this particular instance, it should only be used when
necessary. ByRef parameters and ado recordsets can be a problem.
Secondly, the parameter is of type Form and Label30 and Label31 are
unique to your particular form class. This code will work (provided
you are allowing late binding), but if at all possible should be
changed to take the specific type of form that you are using.
'UPGRADE_ISSUE: Form property FormN.ScaleWidth was not upgraded.
' FormN.ScaleWidth = 11940
FormN.Height = VB6.TwipsToPixelsY(8500)
FormN.Width = VB6.TwipsToPixelsX(12060)
FormN.BackColor = System.Drawing.ColorTranslator.FromOle(RGB(rrr,
ggg, bbb))
'UPGRADE_ISSUE: Form property FormN.DrawWidth was not upgraded.
' FormN.DrawWidth = 1
'UPGRADE_ISSUE: Control Label30 could not be resolved because it was within the generic namespace Form.
' FormN.Label30.Width = 8000
'UPGRADE_ISSUE: Control Label31 could not be resolved because []
' FormN.Label31.Width = 8000
'UPGRADE_ISSUE: Control Label30 could not be resolved because []
' FormN.Label30 = TitleS
'UPGRADE_ISSUE: Control Label31 could not be resolved because []
' FormN.Label31 = SubtitleS
'UPGRADE_ISSUE: Control Label30 could not be resolved because []
' FormN.Label30.ForeColor = RGB(r3, g3, b3)
'UPGRADE_ISSUE: Control Label31 could not be resolved because []
' FormN.Label31.ForeColor = RGB(255, 255, 255)
If rrr = 255 And ggg = 255 And bbb = 255 Then
'UPGRADE_ISSUE: Control Label31 could not be resolved
' FormN.Label31.ForeColor = RGB(0, 0, 0)
End If

End Sub

On a somewhat different note -- do you see how I edited the upgrade
issues so that the "click" on comment is gone? I'd recommend that you
do this for any upgraded code that you are posting questions about, as
it makes reading the code MUCH easier and we can probably figure it out
without referring to it. If you want to leave in one instance, that
wouldn't be so much of a problem, but with the wrapping, the code just
gets too busy...
 
It's in the *.Designer.vbfile, I usually click on the form's class and
find all references and then click on the partial class to get to
*.Designer.vbfile.  But really, in both VB6 andVB.Net, you generally
want to work with the designer, not hand code things.




All controls have a Controls property that is a collection of controls
within thatcontrol.  So, a group box is acontrolthat defines an area
on the form that contains other controls, and it's easy to step through
and address the controls in that container.  If you move thecontrolto
another container then it's no longer in the collection, but if you
move the container all of it's controls remain within in the container.

It's basically a more powerful way of doingcontrolarrays.  But it is
slightly different, so an automatic upgrade won't be using this method.

I found the *.designer.vb where this stuff is.

Me._Text2_3 = New System.Windows.Forms.TextBox
Me._Text2_2 = New System.Windows.Forms.TextBox
Me._Text2_1 = New System.Windows.Forms.TextBox
Me._Text2_0 = New System.Windows.Forms.TextBox
Me._Text1_15 = New System.Windows.Forms.TextBox
Me._Text1_14 = New System.Windows.Forms.TextBox
Me._Text1_13 = New System.Windows.Forms.TextBox
Me._Text1_12 = New System.Windows.Forms.TextBox

followed by

Me.Text2.SetIndex(Me._Text2_12, CType(12, Short))
etc.

Fortunately this has been done by the conversion wizard. If I have to
do this myself, what is the right way of doing it? For example, my
Form2 needs 16 textboxes called Text1, 16 of Text2, 16 Label1 and 16
Label2. Then there are some commands for calculations. How should I do
this? In VB6, it could be done nicely and cleanly.
 
I found the *.designer.vb where this stuff is.

Like I said in the part I snipped, you don't want to go editing the
designer file anymore than you want to be opening a frm file in a text
editor and editing it -- it's possible, but absent specific reasons and
experience, not a good idea.
Me._Text2_3 = New System.Windows.Forms.TextBox
Me._Text2_2 = New System.Windows.Forms.TextBox
Me._Text2_1 = New System.Windows.Forms.TextBox
Me._Text2_0 = New System.Windows.Forms.TextBox
Me._Text1_15 = New System.Windows.Forms.TextBox
Me._Text1_14 = New System.Windows.Forms.TextBox
Me._Text1_13 = New System.Windows.Forms.TextBox
Me._Text1_12 = New System.Windows.Forms.TextBox

followed by

Me.Text2.SetIndex(Me._Text2_12, CType(12, Short))
etc.

Fortunately this has been done by the conversion wizard. If I have to
do this myself, what is the right way of doing it? For example, my
Form2 needs 16 textboxes called Text1, 16 of Text2, 16 Label1 and 16
Label2. Then there are some commands for calculations. How should I do
this? In VB6, it could be done nicely and cleanly.

You'd do it in the designer -- dragging the TextBox from the ToolBox to
the appropriate place on your form. Pretty much like you did in VB6
originally.

BTW - I'd recommend changing the names (in the designer) of the various
controls to something appropriate.
 
Like I said in the part I snipped, you don't want to go editing the
designer file anymore than you want to be opening a frm file in a text
editor and editing it -- it's possible, but absent specific reasons and
experience, not a good idea.









You'd do it in the designer -- dragging the TextBox from the ToolBox to
the appropriate place on your form.  Pretty much like you did in VB6
originally.

Yes, I can drag the textbox and create 32 of them but how do I get
them into an array without messing with the designer.vb?
BTW - I'd recommend changing the names (in the designer) of the various
controls to something appropriate.

You mean txtVolume and txtDensity instead of Text1 and Text2?
 
Yes, I can drag the textbox and create 32 of them but how do I get
them into an array without messing with the designer.vb?

Add a sub new to your Forms.vb file, then you can add the code there. The
IDE is pretty smart about that - even adding the call to InitializeComponets.

Alternativly, Form_Load :)
 
Add a sub new to your Forms.vb file, then you can add the code there.  The
IDE is pretty smart about that - even adding the call to InitializeComponets.

Alternativly, Form_Load :)

Sorry, I cannot understand this at all. What sub new do I add and what
do I write in the subroutine? In VB6, control arrays were formed
straight by copying a control to another. What do I have to do here in
VB Express 2008? Thanks.
 
Yes, I can drag the textbox and create 32 of them but how do I get
them into an array without messing with the designer.vb?

Instead of an array, you have a collection -- the collection is created
automatically based upon the fact that they share a common "parent"
control (a container control).

Take for example a Tab control -- you drag that to to the form from the
ToolBox, then you drag your TextBoxes from the ToolBox to the Tab.
Presto, you have a collection of TextBoxes.

You can do the same thing with any container -- split control, group
box, panel, tab. Anything that can hold another control.
You mean txtVolume and txtDensity instead of Text1 and Text2?

Exactly.
 
Instead of an array, you have a collection -- the collection is created
automatically based upon the fact that they share a common "parent"
control (a container control).

If I understand right, a collection will not be an array, or in other
words, I cannot refer to the 4th element as Text1(3).Text. In that
case, it won't serve my purpose. I need to do mathematical
calculations with vectors and show some numbers in text boxes, so I
need to read the values in Text1(k).Text and show calculated values in
Text2(i).Text. The same number of labels are made visible and their
text (caption) is often taken from an input file.

You are suggesting that I could put these in a frame or some
container, so that they will all belong to one group (collection).
This would not be a problem, but I would like to address the elements
of the collection by an index.

What exactly has the conversion wizard done? I am able to make the
same calculations in the converted code, but I don't understand very
much of what the new code means. It has given separate names to each
label and text box. Then it has formed the arrays because the code
addressing Text1(k).Text has not changed.
Take for example a Tab control -- you drag that to to the form from the
ToolBox, then you drag your TextBoxes from the ToolBox to the Tab.
Presto, you have a collection of TextBoxes.

You can do the same thing with any container -- split control, group
box, panel, tab.  Anything that can hold another control.



Exactly.

Thanks. I understand the VB.net terminology quite poorly, which is one
reason why I am asking these stupid questions.
 
C said:
Sorry, I cannot understand this at all. What sub new do I add and what
do I write in the subroutine? In VB6, control arrays were formed
straight by copying a control to another. What do I have to do here in
VB Express 2008? Thanks.


Some things you should know:

- You've seen there are two files for one Form. The (usually hidden) designer part
and the visible code file.

- The designer part contains Sub InitializeComponent that must be called in the
Form's constructor (Sub New) because it creates the controls and so on.

- With "normal" classes, if you don't write your own constructor(s), the VB compiler
automatically adds a default constructor which just calls the base class constructor.
This constructor is compiled into the assembly (exe/dll) but it's not visible in the
source code.

- If you add a new Form to the project, it does not have a visible constructor, too.
With a Form class, VB also creates a default constructor but that one also contains
a call to InitializeComponent.

- If you add your own constructor to your own Form class, do it in the form1.vb
file (not in the designer file). You must not forget to call InitializeComponent
there. Otherwise all controls were missing. And that's what Tom
meant: As soon as you add your own constructor, the IDE automatically inserts
the call to InitializeComponent.

- With upgraded projects it's a little bit different because form1.designer.vb does
include a constructor (also calling InitializeComponent). If you added your own
constructor in form1.vb, you'd have two of them (with same signature) which is
not allowed.

Back to your goal to create an array of Textboxes. You have to do it inside
the constructor after calling InitializeComponent.

So, inside Form1.vb add:

private myTextboxes as textbox()

And inside Form1.designer.vb change the constructor to make it look like this:

sub new
InitializeComponent

mytextboxes = new textbox() {text0, text1, text2} '<<<<<<< line to add
end sub

Sometimes there is already a call to "class_initialize_renamed" which you find
inside form1.vb. If that's the case, you can add the line "mytextboxes =..."
in sub class_initialize_renamed instead of directly in Sub New.


Later in code, you can refer to the textboxes by index by writing

mytextboxes(0).text = "I'm a textbox"
 
Armin Zingler said:
- If you add a new Form to the project, it does not have a visible
constructor, too. With a Form class, VB also creates a default
constructor but that one also contains a call to InitializeComponent.

Actually, if you add a form to a project it DOES have a constructor.
This constructor is in the designer file, but is present.

And if you need to put your own code inside of it, that is OK -- it
won't mess anything up, as long as you do it after the call to the base
constructor and after the call to InitializeComponent.
 
J.B. Moreno said:
Actually, if you add a form to a project it DOES have a constructor.
This constructor is in the designer file, but is present.

Before writing all this, I was not sure in every case. So I've tried it.
If I add a new form, it does not contain a constructor in the source code.
I would not have written it without trying it first. I'm using VS 2008 Prof.

This is the whole designer file:

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
Inherits System.Windows.Forms.Form

'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer

'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Text = "Form1"
End Sub

End Class

I do not see a constructor there. The compiler creates it when compiling.

And if you need to put your own code inside of it, that is OK -- it
won't mess anything up, as long as you do it after the call to the base
constructor and after the call to InitializeComponent.

As I wrote

I agree. However, putting additional constructor code into form1.vb, you have your
own constructor code all there and always visible.
 
Armin Zingler said:
Before writing all this, I was not sure in every case. So I've tried it.
If I add a new form, it does not contain a constructor in the source code.
I would not have written it without trying it first. I'm using VS 2008 Prof.

Everyone: sorry, Armin Zingler is exactly right. And I was entirely
wrong: an explicit constructor is not created. I was *sure* one was,
but of course I was wrong...
 
Back
Top