Solved

Global Variables

Posted on 2004-11-01
1,910 Views
Last Modified: 2010-04-15
I have a modal login dialog box that sets a string variable and then the dialog box closes.  (It is a login dialog box and if correct username and password, it sets the string to the value of the username.)  I need to be able to access the value of this variable from the main form of my application.  In C++ the modifier would be "external".  Then, this variable would be accessible anywhere in the application.  I need to be able to access the username from anywhere in the application so that the app will be able to determine the type of privileges the current user has when modifying the database.

Thanks in advance.
0
Question by:fly412s
    20 Comments
     
    LVL 15

    Expert Comment

    by:Timbo87
    On the login form, add local variables for the user name and password, then add public properties that retrieve the values.

    // Form1 class

    private string username;

    public string Username
    {
         get
         {
              return username;
         }
         set
         {
              username = value;
         }
    }

    Store the text box values in the variables when they click OK. Then in the main form.

    Form1 frm = new Form1();
    if(frm1.ShowDialog() == DialogResult.OK)
    {
         // do something with frm.Username
    }
    0
     
    LVL 15

    Expert Comment

    by:Timbo87
    Small typo, that should be frm.ShowDialog(), not frm1.ShowDialog().
    0
     

    Author Comment

    by:fly412s
    That won't work because the main form calls the login form.  I do not have an "ok" button.  Just a "Login" button and "exit" button function to exit from the application.  The "login" button click event calls a query and if username and password are found, the login dialog box closes and allows the user access to the main application form.
    0
     
    LVL 15

    Expert Comment

    by:Timbo87
    It still works. You can perform all the user validation in the login form and still expose a username to the main form if it succeeds.
    0
     

    Author Comment

    by:fly412s
    I don't understand...Here is a portion of the code that calls the Login form.  

    partial class MainForm : Form
          {
                LoginForm loginForm = new LoginForm();


                public MainForm()
                {
                      InitializeComponent();
                      loginForm.Show(this);
                }

          }

    The MainForm needs to have the string Username established in the LoginForm.
    0
     
    LVL 15

    Expert Comment

    by:Timbo87
    loginForm.Show(this);
    string username = loginForm.Username;

    Once the user is authenticated in the login form, put the username in a publicly accessible property (in LoginForm). A form is just a class and can have properties just like any other class.
    0
     

    Author Comment

    by:fly412s
    I've already tried that suggestion.  It doesn't work.  Is there any modifier in c# that acts like the extern modifier in c++?
    0
     
    LVL 15

    Expert Comment

    by:Timbo87
    No offense, but you must be doing something wrong. I've used this technique to do exactly what you want to do before. Global variables like C++'s do not exist in .NET either.
    0
     
    LVL 6

    Expert Comment

    by:ryerras
    You can do that. Its called static variable. Lets try this

    In your MainForm

    private static string _userName = null;
     public static string UserName
    {
       get
       {
         return _userName;
       }
       set
       {
         _userName = value;
       }
    }

    In your child form, when the user is authenticated, just say MainForm.UserName= "username"; and you are done

    Let me know if you got any questions
    0
     

    Author Comment

    by:fly412s
    Still not working.  Here is the code from the MainForm:

    partial class MainForm : Form
          {

                private static string _userName = null;
                public static string UserName
                {
                      get
                      {
                            return _userName;
                      }
                      set
                      {
                            _userName = value;
                      }
                }


                public MainForm()
                {
                      InitializeComponent();

                }

                private void MainForm_Load(object sender, EventArgs e)
                {
                      LoginForm loginForm = new LoginForm();
                      loginForm.Show(this);
                      //MessageBox.Show(UserName);
                }

    Here is the code from the LoginForm:

    private void buttonLogin_Click(object sender, EventArgs e)
                {
                      try
                      {
                            conn = connMgr.OpenConnection();
                            OleDbCommand cmd = new OleDbCommand(
                                  "SELECT Username, Password from Usernames "+
                                  "WHERE Username LIKE ?", conn);
                            string userName = "%" + textBoxUserName.Text + "%";
                            cmd.Parameters.Add("User_Name", OleDbType.VarChar);
                            cmd.Parameters["User_Name"].Value = userName;
                            oleDbAdapter.SelectCommand = cmd;
                            oleDbAdapter.Fill(userDataSet, "Usernames");
                            if (userDataSet.Tables["UserNames"].Rows.Count > 0)
                            {
                                  DataRow dr = userDataSet.Tables["UserNames"].Rows[0];
                                  if (dr["Password"].ToString() == textBoxPassword.Text)
                                  {
                                        MessageBox.Show("Successful Login");
                                        connMgr.CloseConnection();
                                        MainForm.UserName = textBoxUserName.Text;
                                        this.Close();
                                  }//end password matches
                                  else
                                  {
                                        MessageBox.Show("Password does not match.");
                                        connMgr.CloseConnection();
                                  }
                            }//end if successful username in database
                            if (userDataSet.Tables["UserNames"].Rows.Count == 0)
                            {
                                  MessageBox.Show("Could not find username");
                                  connMgr.CloseConnection();
                            }//end if unsuccessful username in database

                      }
    0
     

    Author Comment

    by:fly412s
    It seems as if when the application executes, the loginform is called first and then the mainform loads second so that there is never a chance for the UserName variable to be initialized by the loginform's username textbox.
    0
     
    LVL 6

    Expert Comment

    by:ryerras
    This should work. Are you checking the user name in the main form after the child form closes. If you do whats the result. Please put break points and try to debug. Let me know if you get any error
    0
     
    LVL 6

    Expert Comment

    by:ryerras
    Hmm now you know why its not happening, may be you should alter the way your forms load. May be you should load the main form first, then hide it and show the user the loginform only, after the authentication, make the visibility of the main form to true. That way, all the variables in the main form would still be available to the child form
    0
     

    Author Comment

    by:fly412s
    The program starts in the Program class as follows:

    namespace Logbook
    {
          static class Program
          {
                /// <summary>
                /// The main entry point for the application.
                /// </summary>
                [STAThread]
                static void Main()
                {
                      
                      Application.EnableVisualStyles();
                      Application.EnableRTLMirroring();
                      Application.Run(new MainForm());
                }
          }
    }

    As you can see, the MainForm is called first.  It is from within the MainForm that the LoginForm is called.  So, as far as I can tell, the MainForm should load first, then the LoginForm, since the LoginForm is called by the MainForm???????
    0
     
    LVL 6

    Expert Comment

    by:ryerras
    It looks like that. But remember, this is all one thread. A thread returns only when its work is done, thats called synchronous programming. After invoke Application.Run(new MainForm()), it goes to the MainForm_Load, this method loads the child window, so you see the child form, you still havent seen the main form yet, since its load method is not finished yet. remember its still in the single thread, so its not returned to the user yet. Thats why you dont see the mainform until you close the child window
    0
     

    Author Comment

    by:fly412s
    OK, so what do you recommend to solve my dilema?
    0
     
    LVL 6

    Accepted Solution

    by:
    Well. a correction to what I said, your main form should be displayed, if the child form is a non modal form, which looks like it from the Show method. But I dont understand what is that argument "this" for Show method, I am not aware of a Show method which takes an argument.. Anyway, if any of this does not solve your problem

    Put that static variable stuff in the child form instead of MainForm and after the user is authenticated, assign the user name to the child windows static variable.

     if (dr["Password"].ToString() == textBoxPassword.Text)
                             {
                                  MessageBox.Show("Successful Login");
                                  connMgr.CloseConnection();
                                  LoginForm.UserName = textBoxUserName.Text;
                                  this.Close();
                             }//end password matches

    Dont worry, your static variable will still be there, even if you close the window. In your main form, access the user name as
    LoginForm.UserName. It should work.
    0
     

    Author Comment

    by:fly412s
    The "this" is passed to the Show method as a "pointer" to the parent form, the MainForm.  Also, the problem of how the application loads itself is solved by calling the ShowDialog method of the LoginForm instead of the Show method.  The ShowDialog method seems to stop everything until that "dialog box" (the LoginForm) is closed.  Once the ShowDialog method is called, the application class (the Program class) stops executing until the ShowDialog returns (or closes, i.e., the "Login" button in the LoginForm is clicked).  Then the application continues loading the MainForm and the variable I need is exactly where you said it would be: MainForm.UserName.
    0
     
    LVL 6

    Expert Comment

    by:ryerras
    so is everything ok now?
    0
     

    Author Comment

    by:fly412s
    Works great, thank you.  Did I make sense in the above explanation?
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Anonabox PRO Tor & VPN Router

    PRO is the most advanced way to fortify your privacy and online anonymity by layering the Tor network with VPN services. Use both together or separately, and without needing to download software onto your devices.

    Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
    We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
    With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…
    With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…

    884 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    24 Experts available now in Live!

    Get 1:1 Help Now