How to access variables defined on another form

  • Thread starter Thread starter Young
  • Start date Start date
Y

Young

Hi,

I am currently porting a VB6 app to VB.NET 2008 and am stucked big tim.

I've got 2 forms in VB.Net (Form1 and Form2) each with a public string
variable defined as Dim sv_str_1 as string.

I also got a Sub that accept a form and work on the variable.

Eg.

Sub DispValue(frm as form)
Msgbox frm.sv_str_1
End sub

This will display whatever is in sv_str_1 for the form. Eg.

1) If I call DispValue(Form1), it will display sv_str_1 for Form1
2) Calling DispValue(Form2) will display sv_str_1 from Form2.

This works in VB6 but not VB.Net.

In VB6, I can also do this:

Dim MyWorkForm as Form
Set MyWorkForm = Form1
Msgbox MyWorkForm.sv_str_1

This will display the string value for Form1.

In VB.NET, Msgbox MyWorkForm.sv_str_1 will generate an error when
compiling - it says sv_str_1 is not a member of System.Windows.Forms.Form.

This Msgbox Form1.sv_str_1 works in .NET because I did not assign Form1 to a
variable.

This is the same for accessing controls on a VB.NET form. For example, I can
do this in VB6:

Dim MyWorkForm as Form
Set MyWorkForm = Form1
Msgbox MyWorkForm.TextAdd.Text

This will display the value for textbox "TextAdd"

But same does not work in VB.NET. Same error. It says that TextAdd is not a
member of System.Windows.Forms.Form.

Is there a way around this?

TIA

Young
 
I am currently porting a VB6 app to VB.NET 2008 and am stucked big tim.

I've got 2 forms in VB.Net (Form1 and Form2) each with a public string
variable defined as Dim sv_str_1 as string.

I also got a Sub that accept a form and work on the variable.

Eg.

Sub DispValue(frm as form)
    Msgbox frm.sv_str_1
End sub

This will display whatever is in sv_str_1 for the form. Eg.

1) If I call DispValue(Form1), it will display sv_str_1 for Form1
2) Calling DispValue(Form2) will display sv_str_1 from Form2.

This works in VB6 but not VB.Net.

In VB6, I can also do this:

Dim MyWorkForm as Form
Set MyWorkForm = Form1
Msgbox MyWorkForm.sv_str_1

This will display the string value for Form1.

In VB.NET, Msgbox MyWorkForm.sv_str_1 will generate an error when
compiling - it says sv_str_1 is not a member of System.Windows.Forms.Form..

This Msgbox Form1.sv_str_1 works in .NET because I did not assign Form1 to a
variable.

This is the same for accessing controls on a VB.NET form. For example, I can
do this in VB6:

Dim MyWorkForm as Form
Set MyWorkForm = Form1
Msgbox MyWorkForm.TextAdd.Text

This will display the value for textbox "TextAdd"

But same does not work in VB.NET. Same error. It says that TextAdd is nota
member of System.Windows.Forms.Form.

Is there a way around this?

Yes. You need to 1) read the error message and understand what it
actually says (it's all right there!), and 2) get the types in
variable declarations right. Specifically:

Dim MyWorkForm As Form1

That will let you access all members of Form1. VB.NET requires you to
either get the type right, or, if you truly want to resolve all
properties and methods at run-time, you should make sure that you have
"Option Strict Off" (it's off by default), and then declare variable
as Object:

Dim MyWorkForm As Object

Then it'll compile any property/method access, and if you get it
wrong, it'll fail at run-time. But, generally, this isn't a good idea
to use that much.
 
Young,

What you see comes probable by the strange behaviour of the visibility of
the Dim statement in VB.

As you take it as standard for you to use only Dim in a method and outside
only:
private which means that it is visible totally for the class
friend which means that it is visible only inside the project
public which means that it is visible everywhere

This can also be used combined with protected, but that I leave because then
I make it probably only more difficult.
Protected is very usable with AspNet.

As you do it like this then you overcome mostly the problems, which you have
now.

I hate the sentence but here it fits, this can be good practice in VB
versions later then VB6

To make the Dim more inconsequent but kept this way so to have no different
language behaviour in the versions.
A Dim used in a module is everywhere public
A Dim used in a class is everywhere private

Cor
 
Hi Young,

I don't know the exact method by which VB6 forms let you access the values
of their controls but I do know that C# and therefore probably VB.Net as
well are rather stricter about how you can access those values. Please see
my replies below the relevant parts of your message:

Young said:
[...]
I've got 2 forms in VB.Net (Form1 and Form2) each with a public string
variable defined as Dim sv_str_1 as string.

Based on what you've said later on, I'm assuming you have the following
situation:

dim Form1 = new System.Windows.Forms.Form
dim Form2 = new System.Windows.Forms.Form

Form1.sv_str_1 = "..."
Form2.sv_str_1 = "..."

This won't work, because the System.Windows.Forms.Form class does not have a
public member variable or settable property named sv_str_1. This sounds
close to the error you're getting.

I think in your VB6 forms that sv_str_1 was a textbox control inside the
forms, and VB6 allowed you to access the current text value inside those
text box controls by using the dot operation. But in VB.Net access has been
tightened up to the level of C# access rules, so you can no longer do that.
I think you can access those things in another way:

dim sv_str_1 as System.Windows.Forms.TextBox

dim Form1 = new System.Windows.Forms.Form
sv_str_1 = new System.Windows.Forms.TextBox
sv_str_1.Name = "sv_str_1"
sv_str_1.Parent = Form1

dim Form2 = new System.Windows.Forms.Form
sv_str_1 = new System.Windows.Forms.TextBox
sv_str_1.Name = "sv_str_1"
sv_str_1.Parent = Form2

....

sub DispValue(frm as System.Windows.Forms.Form)
MsgBox frm.Controls["sv_str_1"].Text
end sub

HTH

Yawar
 
Cor,

Using Dim outside method scope was already considered bad coding practice
in VB 6 and so it is in VB.Net



HTH

Michel
 
You need to restrict your references to objects that are part of the Form class.

Change the reference frm.sv_str_1 to frm.controls("sv_str_1").text()

Private Sub DispValue(ByVal frm As Form)
MsgBox(frm.Controls("sv_str_1").Text())
End Sub
 
A Dim used in a module is everywhere public
A Dim used in a class is everywhere private

Cor

Isn't it wrong? AFAIK in vb.net, Dim's default access modifier is
"Private" whether it's a Class or a Module when variable is declared
in Class-level or Module-level, and Dim is public in Structures.

http://msdn.microsoft.com/en-us/library/7ee5a7s1(VS.80).aspx

http://msdn.microsoft.com/en-us/library/z3w7sxtd(VS.71).aspx
...says: "The Dim statement at module level defaults to Private if you
do not use any accessibility keywords." which is same for classes.


ralpugan
 
You are right, I have mixed this up with the accibility of a method.
I never use the Dim outside method scope.

Sorry

Cor

A Dim used in a module is everywhere public
A Dim used in a class is everywhere private

Cor

Isn't it wrong? AFAIK in vb.net, Dim's default access modifier is
"Private" whether it's a Class or a Module when variable is declared
in Class-level or Module-level, and Dim is public in Structures.

http://msdn.microsoft.com/en-us/library/7ee5a7s1(VS.80).aspx

http://msdn.microsoft.com/en-us/library/z3w7sxtd(VS.71).aspx
...says: "The Dim statement at module level defaults to Private if you
do not use any accessibility keywords." which is same for classes.


ralpugan
 
Looks like

Msgbox MyWorkForm.sv_str_1

Is the culprit here. Does your Vb6 solution have Option Explicit set at the
top of the code page? You are attempting to TypeCast a form to form1 in a
manner like LateBinding. While this is fine for VB6, this isn't boding well
for .Net.

MyWorkForm is declared as a Form not as Form1, so when you want to access
properties and methods specific to a derived contract, you need to cast it
as such.

In C#, we use ((Form1)MyWorkform).sv_str_1
In VB.Net, I believe we use:

(CType(MyWorkForm, Form1)).sv_str_1

or

(DirectCast(MyWorkform, Form1)).sv_str_1

This should correct the issue at hand.

A lot of folks threw in "best practices", I am of the mind that as long as
it works for you, that is your best practice. However, I still feel that
there is a "better than others" approach to this scenario.

In my mind, when I hear "I need to share data values in two or more forms",
I immediately think of a class object or structure with some hot wiring for
sharing. But that is up to you.

You know folks are saying time and again that we (developers) need to get
that logic out of the UI and yet rarely do you see responses to posts with
MVP/MVC examples. Seems this just perpetuates the cycle. For many
developers there is no affect on them since they are Principles of
consulting firms that get paid to recover project that are failing or they
work in companies that have/havenot coding standards that address this. For
the rest of the denizens, there is little solice on the topic. So while I
threw in my approach, I didn't provide a sample piece of code because I
would suggest a MVP solution. And while I know this is a migration from VB6
to VB.Net and therefore a lot of work in tweaking the differences, folks
doing the migration shouldn't simply attempt to replicate functionality that
was in a working code base in the next gen compiler, they should be
attempting to maximize the features and "best practices" that brought out
the next gen compiler. And that requires the community to first agree on
"best practices" and then practice them in their community responses.

So for example:

VB6 allowed you to:

Dim MyForm as form
set MyForm = Form1

..Net suggests that you should:

Dim MyForm as form
MyForm = New Form1

Best Practices suggest you should:

Dim MyForm as IWinformFormView
MyForm = MyPresenter.CreateView(MyViews.FormView);

--The presenter (and not the form) then manages updating values between
views. The presenter then handles button clicks, so on and so forth.
--How/If you implement the MVP pattern is up to you. But we should all be
talking this way.
--Perhaps the forums aren't the best place, perhaps thecodeproject.com is
the only place to truely see this in action. But then, the community as a
whole isn't debunking/reinforcing one author's opinion of best practices.
 
Thanks everyone for your help.

I found the directcast option that works.

I completely agree with you but we are short on time and just have to
migrate our VB6 app. to work on .NET as quickly as possible. We cannot
afford to worry about best practice at this stage.

We just find it very frustrating that microsoft changes so many things
without any considerations for their customers. I guess they are big enough
to do what they like.
 
Thanks everyone for your help.

I found the directcast option that works.

I completely agree with you but we are short on time and just have to
migrate our VB6 app. to work on .NET as quickly as possible. We cannot
afford to worry about best practice at this stage.

We just find it very frustrating that microsoft changes so many things
without any considerations for their customers. I guess they are big enough
to do what they like.
 
Back
Top