Visibility of Form1 question.

J

Jamey Bon

I am a C# newbie. I am having a tough time with several issues of scope
and visibility.

In short, why can't I see any of the elements of Form1 (the base form
generated by the "Windows Application Project Wizard") from anywhere else
in my project? For example, why can I not change the text of a TextBox
control from Main() (which is, by default, in the Program class) even
after I have set its visibility to public in Form1? Furthermore, I can
add a class to the project, make sure it and its fields are public,
instantiate an object of that class (say, in Main()) but won't be able to
see that class's public fields from within Form1. This seems to all hold
true even if I am using the fully qualified (starting with the namespace)
name.

This is actually a smaller part of my larger attempt to understand how to
organize a program into a decent object-oriented, modular design. I have
tried to find some good code samples of such, but so far have failed.

So, can someone please put me on the right track to understanding how the
visibility and scope is working in these cases? Thank you very much.

JB
 
M

Morten Wennevik [C# MVP]

Hi Jamey,

If you could show us some code we might spot the errors.

If the fields are public they are visible to everyone, however, they will only be accessible through an instance of the class those fields belong to (unless the fields are static).

public class MyProgram
{
public static void Main()
{
MyForm myForm = new MyForm();
myForm.MyTextBox.Text = "Hello World";

Application.Run(myForm);
}
}

public class MyForm : System.Windows.Forms.Form
{
public TextBox MyTextBox = new TextBox();

public MyForm()
{
this.Controls.Add(MyTextBox);
}
}

The code above lets Main change the text of MyForm's MyTextBox. However, instead of accessing fields directly, you should go through properties..

public class MyProgram
{
public static void Main()
{
MyForm myForm = new MyForm();
myForm.MyText = "Hello World";

Application.Run(myForm);
}
}

public class MyForm : System.Windows.Forms.Form
{
private TextBox MyTextBox = new TextBox();

public string MyText
{
get{ return MyTextBox.Text; }
set{ MyTextBox.Text = value; }
}

public MyForm()
{
this.Controls.Add(MyTextBox);
}
}

This way MyForm will have more control of what gets set in the TextBox. For instance, MyText can test for InvokeRequired before setting the TextBox value.

Having written all this, I think I understand your scenario

public class MyForm : System.Windows.Forms.Form
{
private TextBox MyTextBox = new TextBox();
private static TextBox MyStaticTextBox = new TextBox();

public string MyText
{
get{ return MyTextBox.Text; }
set{ MyTextBox.Text = value; }
}

public MyForm()
{
this.Controls.Add(MyTextBox);
}

public static void Main()
{
MyTextBox.Text = "Hello World"; // ERROR! MyTextBox isn't static
MyStaticTextBox.Text = "Hello WOrld"; // Works because MyStaticTextBox is static
}
}

The code above won't work because Main() is static, which means you can't access fields, properties or methods from MyForm that aren't static. Among all MyForm objects you may create, there will be numerous MyTextBox controls created, one for each MyForm, but there will only be one MyStaticTextBox, shared among all the MyForm objects. For the same reason Main() needs to be static, so that the operating system can access the Main() method, even though there may be no MyForm objects created.
 
P

PS

Jamey Bon said:
I am a C# newbie. I am having a tough time with several issues of scope
and visibility.

In short, why can't I see any of the elements of Form1 (the base form
generated by the "Windows Application Project Wizard") from anywhere else
in my project? For example, why can I not change the text of a TextBox
control from Main() (which is, by default, in the Program class) even
after I have set its visibility to public in Form1? Furthermore, I can
add a class to the project, make sure it and its fields are public,
instantiate an object of that class (say, in Main()) but won't be able to
see that class's public fields from within Form1. This seems to all hold
true even if I am using the fully qualified (starting with the namespace)
name.

This is actually a smaller part of my larger attempt to understand how to
organize a program into a decent object-oriented, modular design. I have
tried to find some good code samples of such, but so far have failed.

So, can someone please put me on the right track to understanding how the
visibility and scope is working in these cases? Thank you very much.

These are some additional comments in addition to Morten's.

1. Using the fully qualified namespace makes no difference to visibility
once the class name can be resolved. The using statement just saves you
having to always use the fully qualified name. If your code compiles that
using / not using fully qualified names makes no difference.

2. Generally I avoid exposing controls outside of the form. However if you
need to do this then I would recommend exposing them from a property.
Internal or public fields are generally not used in any class. Even better,
expose just the property that you need access to, e.g.
internal string StatusText {
set { this.statusTextBox.Text = value;}
}

3. The overall organizational structure of a solution is that you use
internal and private as much as possible within each project. For any
"cross-project" access you use public (note that there is something called a
friend assembly that allows you to see internal members between projects). A
common example where this is used is object construction. Your objects have
internal constructors so outside of that project you can not create these
objects. So you access them through a factory that has a public (and static)
method.

4. As a point of interest if you have no modifier on a field, property etc
then it defaults to the most private modifier that it can be. For example
namespace MyApplication {
class Employee {
Employee()
{...
is an internal class with a private constructor.

PS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top