Wiooo Wiooo - 1 month ago 21
C# Question

Goto (or goto alternative) to use in global scope

I am making a program that connects to a MySQL Database in C#. I have 2 C# Windows Forms that work. One is the main program, and the other is a popup window for connecting to a server. This popup window changes global variables to be used in the other (main app) form.

The one thing I need for this to work is a statement that will go to a specific place in the main app form. The goto statement cannot be used here, as that would be outside of the scope. I need to somehow either make the goto statement usable in the global scope, or come up with an alternative to the goto statement (functions would not be usable in this case, because I need things on the main form to update, so I can't just have a connection function in the secondary form.) Anyone have any ideas?

Here is my code:

Connection Form (Connection.cs):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using SelfService_C_Sharp;

namespace SelfService_C_Sharp
{
public partial class Connection : Form
{
public Connection()
{
InitializeComponent();
}

private void Server_TextChanged(object sender, EventArgs e)
{
}

private void button1_Click(object sender, EventArgs e)
{
Global.cnn.Close();
Global._Server = Server.Text;
Global._Uid = User.Text;
Global._Database = Database.Text;
Global._Pwd = Password.Text;

}
}
}


Main App(Form1.cs):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

namespace SelfService_C_Sharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

Global._Server = "mysql.dunkycart.com";
Global._Uid = "dunkycart";
Global._Database = "dunkycart";
Global._Pwd = "password";
Global.connetionHost = "Server=" + Global._Server + "; Database=" + Global._Database + "; Uid=" + Global._Uid + "; Pwd=" + Global._Pwd + ";";
Connection:
Global.cnn = new MySqlConnection(Global.connetionHost);

Global.ConnetionInfo = "Server: " + Global._Server + " | User: " + Global._Uid;

try
{
Global.cnn.Open();
label2.Text = Global.ConnetionInfo;
label1.Text = "Connection successful.";
//Global.cnn.Close();
}
catch (Exception ex)
{
label1.Text = "Connection failed on error: " + ex.Message;
label2.Text = "Connection failed";
}
}

private void button1_Click(object sender, EventArgs e)
{
var form = new Connection();
form.Show(this);
}
}
}


I want to jump from the end of the code in the Connection.cs file to the point marked "Connection:" in the Form1.cs file.

Answer

Ok, you don't need at all a Goto, just avoid it as it's a bad practice (bad code reading).

There are two options, the easiest one is to use the connection form as Modal, the second one is to use an event. I'm going to add the example for the modal one as it's very easy:

Main App(Form1.cs):

    public Form1()
    {
        InitializeComponent();

        Global._Server = "mysql.dunkycart.com";
        Global._Uid = "dunkycart";
        Global._Database = "dunkycart";
        Global._Pwd = "password";
        Global.connetionHost = "Server=" + Global._Server + "; Database=" + Global._Database + "; Uid=" + Global._Uid + "; Pwd=" + Global._Pwd + ";";

        var conForm = new Connection();
        conForm.ShowDialog(); //This is the key, showing a form as modal will block the execution until the form is closed.

        Global.cnn = new MySqlConnection(Global.connetionHost);

        Global.ConnetionInfo = "Server: " + Global._Server + "  |  User: " + Global._Uid;

        try
        {
            Global.cnn.Open();
            label2.Text = Global.ConnetionInfo;
            label1.Text = "Connection successful.";
            //Global.cnn.Close();
        }
        catch (Exception ex)
        {
            label1.Text = "Connection failed on error: " + ex.Message;
            label2.Text = "Connection failed";
        }
    }

Connection Form (Connection.cs):

    private void button1_Click(object sender, EventArgs e)
    {
        Global.cnn.Close();
        Global._Server = Server.Text;
        Global._Uid = User.Text;
        Global._Database = Database.Text;
        Global._Pwd = Password.Text;
        this.Close();

    }

Also, the modal approach has an advantage, you can add a Cancel button and set the DialogResult of the form to Cancel when it's pressed and to Ok when the button1 is pressed, in this way you can do:

var result = conForm.ShowDialog();

if(result == DialogResult.Cancel)
{
    MessageBox.Show("Connection cancelled.");
    return;
}

EDIT: Your code is not using at all the connection info, you must change it to this to make it work:

        var conForm = new Connection();
        conForm.ShowDialog(); //This is the key, showing a form as modal will block the execution until the form is closed.

        Global.ConnetionInfo = "Server: " + Global._Server + "  |  User: " + Global._Uid;
        Global.cnn = new MySqlConnection(Global.ConnetionInfo);

SECOND EDIT:

If you want to use the same code for connect on startup or reconnect from a button, just move the code to a function:

public Form1()
{
    InitializeComponent();
    Connect();
}

//Assume there is a button called reconnectButton to reconnect.
private void reconnectButton_Click(object sender, EventArgs e)
{
    Connect();
}

void Connect()
{
    Global._Server = "mysql.dunkycart.com";
    Global._Uid = "dunkycart";
    Global._Database = "dunkycart";
    Global._Pwd = "password";
    Global.connetionHost = "Server=" + Global._Server + "; Database=" + Global._Database + "; Uid=" + Global._Uid + "; Pwd=" + Global._Pwd + ";";

    var conForm = new Connection();
    conForm.ShowDialog(); //This is the key, showing a form as modal will block the execution until the form is closed.

    Global.cnn = new MySqlConnection(Global.connetionHost);

    Global.ConnetionInfo = "Server: " + Global._Server + "  |  User: " + Global._Uid;

    try
    {
        Global.cnn.Open();
        label2.Text = Global.ConnetionInfo;
        label1.Text = "Connection successful.";
        //Global.cnn.Close();
    }
    catch (Exception ex)
    {
        label1.Text = "Connection failed on error: " + ex.Message;
        label2.Text = "Connection failed";
    }
}