Resolved this. works, but form1. does not, confused..

Program4Food

Active member
Joined
Nov 22, 2021
Messages
40
Programming Experience
10+
See the code below, I can call this. to minimize the form (form1, the only form in the project), but if I try to call it directly (like I used to be able to do in old VB) by calling it form1., I get an error. I do not understand why I cant call the form directly...

Screen shot showing VS2012 error is attached.

I am self taught so my knowledge and understanding is growing, but is limited. :-( Thank you for your time.

calling a form directly by name does not work:
        private void Form1_Load(object sender, EventArgs e)
        {

           //  this.WindowState = System.Windows.Forms.FormWindowState.Minimized;

             Form1.WindowState = System.Windows.Forms.FormWindowState.Minimized;

        }
 

Attachments

  • callingaformdirectlygiveserrors.jpg
    callingaformdirectlygiveserrors.jpg
    48.7 KB · Views: 4

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
When you use the type name to refer to a form in VB you are using the default instance of that type. That is a VB-specific feature, so you cannot do the same thing in C#. Default form instances are a somewhat contentious feature in VB anyway. They do make things easier for beginners and migrating VB6 developers but they also encourage developers to think of forms differently than they do other objects and ignore good OO practices. You can read a bit of an explanation of default form instances that I wrote here.

In C#, if you want an instance of a form then you have to create one, just as you do for any other type. If you want to be able to refer to that instance elsewhere in your application then you need to pass a reference to that object around, just as you do for any other type.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
You can somewhat simulate default instances in C# with some static members. I strongly recommend against doing that - doing things the "proper" way is not hard if you understand the principles involved and few experienced C# developers lament the lack of default instances - but I can show you how if you're really determined to know.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
By the way, you should not be referring to the default instance of a form inside that form in VB anyway. If you want to refer to the current object in VB then you use Me, either implicitly or explicitly, just as you use this in C#. That code would have prompted a compiler warning in VB, if I'm not mistaken.
 

Program4Food

Active member
Joined
Nov 22, 2021
Messages
40
Programming Experience
10+
I need more of a layman's explanation, several concepts of more modern programming & development studios I have yet to grasp, such as static members, default instances.

I will at one point bang out enough code and read enough text to finally grasp these things better but right now its fog on my battlefield.

If I cannot call form1. directly, as I used to... how then would I call form1 by a given name? I foresee having 2 or 3 forms on a project and wanting to say, change the title of form2. If I am doing this from form1 (say button press event), I cannot use this. to call form2's text property.

I went back and re-read what I wrote, and honestly, I hope it makes sense.

Thank you all-
Andrew
 

Program4Food

Active member
Joined
Nov 22, 2021
Messages
40
Programming Experience
10+
By the way, you should not be referring to the default instance of a form inside that form in VB anyway. If you want to refer to the current object in VB then you use Me, either implicitly or explicitly, just as you use this in C#. That code would have prompted a compiler warning in VB, if I'm not mistaken.


Most of my VB was with 6.0, so... that may explain a lot. (Yeah, Im getting old... part of my my mind is not as sharp as it once was, if it ever was)
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
I need more of a layman's explanation

Did you follow the link to my blog post that I provided? If not, please do so. I shouldn't have to prompt you to do that. If you have, what exactly don't you understand?
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
Most of my VB was with 6.0, so... that may explain a lot. (Yeah, Im getting old... part of my my mind is not as sharp as it once was, if it ever was)

Default instances were added to VB.NET in 2005. The first two versions lacked that feature. I don't think Microsoft ever said so explicitly but the impression seemed to be that they did it to make VB.NET work more like VB6 in that regard and thus make it easier for VB6 developers to migrate to VB.NET, both for existing and new code. C# didn't have that baggage so the authors of C# never felt the need to add the feature. As I said, no C# developer who doesn't have a VB background has ever lamented that lack, as far as I've ever heard.

Think about how you would handle the same situation for other objects. Let's say that you populated a DataTable from a database in Form1 and you wanted to use that data in Form2. You couldn't just pluck a reference to the DataTable object out of thin air, even in VB. You'd have to pass a reference from Form1 to Form2 somehow, which would require setting a field or property in Form2 or calling a method and passing an argument. If forms are objects like any other, why should passing a reference to a form around your application be any different to passing a reference to any other object? It shouldn't and it isn't.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
If you're not really sure how you would pass data between forms in general then that's probably a principle that you should understand sooner rather than later. If you understand how to do that for any type then you understand how to do it for forms, so the lack of default instances becomes a non-issue. That blog of mine also includes a three-part post on using data among multiple forms. You should read all three parts. The first part deals specifically with default instances in VB, so that might make a few concepts clearer, even if you never actually use the information provided.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
On an unrelated note, is there a specific reason that you're still using VS 2012? Given that all versions since have provided a free Community edition, I would suggest upgrading to something more recent. VS 2022 is the latest version but, while it seems to be working pretty well, it will still have a few bugs that older versions don't. It also lacks support for some extensions that you can use in earlier versions. If either of those things is an issue for you, you might choose VS 2019 instead. I can't really recommend using anything older than that unless you have some specific reason for it.
 

Program4Food

Active member
Joined
Nov 22, 2021
Messages
40
Programming Experience
10+
Did you follow the link to my blog post that I provided? If not, please do so. I shouldn't have to prompt you to do that. If you have, what exactly don't you understand?

I did look at it, I did not read it in detail.. as I read over it much of it was over my head. I will study it in more depth. Thank you for posting the information, and linking to it.

If I am going to grow, I really need to get a handle on many things that I do not understand.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
I did not read it in detail.

You definitely should. You may find that something that seems confusing at first becomes less so when you have more information, including examples. We can only dumb things down so much. Programming is a technical pursuit so, no matter how hard we try to put things in terms a layperson can understand, it's often going to require some technicality in its explanation.
 

Program4Food

Active member
Joined
Nov 22, 2021
Messages
40
Programming Experience
10+
I finally solve it, I don't fully understand how it works, but it's okay, I'm not smart enough to comprehend anyway.
I do have a book coming on winforms with C# so maybe later when I have had some time to read the book
and bang out some code Ill have a better understanding. Maybe.

So, amywho... here is some code snippit I have working which will min/max/show/hide Form2 from
buttons placed on Form1:


Needed to set Form2 to null first, I presume I am giving Form2 object an alias of F2,
Im still trying to understand it.



C#:
    public partial class Form1 : Form
    {



        Form2 F2 = null;




C#:
       private void ActionShowForm2(object sender, EventArgs e)
        {

            if (F2 == null)
            {
                F2 = new Form2();
                F2.Show();
            }
            else
            {
                F2.Show();
                F2 = null;
            }
        }


        
        private void ActionHideForm2(object sender, EventArgs e)
        {

            if (F2 == null)
            {
                F2 = new Form2();
                F2.Hide();
            }
            else
            {
                F2.Hide();
                F2 = null;
            }

        }



        private void ActionMinimizeForm2(object sender, EventArgs e)
        {

            if (F2 == null)
            {
                F2 = new Form2();
                F2.WindowState = FormWindowState.Minimized;

            }
            else
            {
                F2.WindowState = FormWindowState.Minimized;
                F2 = null;
            }


        }

        private void ActionRestoreForm2(object sender, EventArgs e)
        {

            if (F2 == null)
            {
                F2 = new Form2();

                F2.WindowState = FormWindowState.Normal;
                F2.Show();
              
            }
            else
            {
                F2.WindowState = FormWindowState.Normal;
                F2.Show();


                F2 = null;
                
            }

        }
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,445
Location
Chesapeake, VA
Programming Experience
10+
Yikes! By setting F2 to null in your else clauses, you are going to end up with multiple Form2 windows since you are basically orphaning the current instance.
 
Last edited:

Program4Food

Active member
Joined
Nov 22, 2021
Messages
40
Programming Experience
10+
Yikes! By setting F2 to null in your else clauses, you are going to end up with multiple Form2 windows since you are basically orphaning the current instance.
Ahh, Ill comment out the =null of the subroutines.. With help of folk like you, I will slowly learn!

I wasnt sure if I needed to return the form to NULL state or not, so I did it... VS didnt moan at me so the code compiles but "its not good".

Thank you!
 
Last edited by a moderator:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,445
Location
Chesapeake, VA
Programming Experience
10+
Try:
Without using Lazy:
Form2 _form2;

Form2 EnsureForm2()
{
    if (_form2 == null)
        _form2 = new Form2();
    return _form2;
}

void btnShow_Click(object sender, EventArgs e)
    => EnsureForm2().Show();

void btnHide_Click(object sender, EventArgs e)
    => EnsureForm2().Hide();

void btnMinimize_Click(object sender, EventArgs e)
    => EnsureForm2().WindowState = FormWindowState.Minimized;

void btnRestore_Click(object sender, EventArgs e)
{
    EnsureForm2().WindowState = FormWindowState.Normal;
    EnsureForm2().Show();
}

Using Lazy:
Lazy<Form2> _form2;
Form2 MyForm2 => _form2.Value;

Form1()
{
    InitializeComponent();
  
    _form2 = new Lazy<Form2>(() => new Form2());
}

void btnShow_Click(object sender, EventArgs e)
    => MyForm2.Show();

void btnHide_Click(object sender, EventArgs e)
    => MyForm2.Hide();

void btnMinimize_Click(object sender, EventArgs e)
    => MyForm2.WindowState = FormWindowState.Minimized;

void btnRestore_Click(object sender, EventArgs e)
{
    MyForm2.WindowState = FormWindowState.Normal;
    MyForm2.Show();
}
 

Program4Food

Active member
Joined
Nov 22, 2021
Messages
40
Programming Experience
10+
Ahh... much more efficient, and cleaner. THANK YOU!!

I am doing 3 new things at once, so I value your help! I am learning a new Visual Studio, dotNet and C#.

I have many years of VB 6.0 under the hood, a lot of updates and changes = A lot of new things to learn!
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
4,250
Location
Sydney, Australia
Programming Experience
10+
This:
C#:
if (_form2 == null)
should be this:
C#:
if (_form2 == null || _form2.IsDisposed)
When you close a form that was displayed by calling Show, that form object is disposed and cannot be shown again, thus a new instance would need to be created.

Also, I would generally use a read-only property rather than a method. That feels a bit more natural to me, but it amounts to the same thing.
 
Top Bottom