简体   繁体   中英

Calling the initial class from inside an object C#

I am creating a Windows Form app in C#, I'm enforcing password protection. I'm sorry for the poor title and explanation, as you can tell I'm an amateur.

The form that loads upon login is a class that is called from within Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace POS
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Login());
        }
    }
}

The class is simply called Login. Once the user has successfully authenticated, I create a new object of a class, hide the Login form and open a new class.

namespace POS
{
    public partial class Login : Form
    {
        RiverbankTeaRooms main = new RiverbankTeaRooms();
        private void Enter_Click(object sender, EventArgs e)
        {
            bool found = false;
            try
            {
                // Search through database through dr[1] (Table 2) for matching string.
                foreach (DataRow dr in dra)
                {
                    if (dr[1].ToString() == Code.Text)
                    {
                        found = true;

                        // Open main form.
                        main.SignedIn = true;
                        main.Show();
                        this.Hide();
                        break;
                     }
                }
                if (found == false)
                {
                    // Incorrect password.

                    Code.Text = "Incor";
                }
            }
            catch
            {
                // Error, most likely with Database.
                Code.Text = "Error";
            }
        }
    }
}

This works perfectly fine... To open the program and authenticate the user however I wish to be able to logout and open the Login form again from within the RiverbankTeaRooms class. I don't know how I'd be able to re-open the form Login again, as it has only been hidden, but I can't figure out how to do Login.Show(); I can't create a new instance of login inside the main form, because the RiverbankTeaRooms form won't be able to close.

This is driving me crazy, and sorry for the poor explanation!

I would like to suggest you to change the flow of the program.

Instead of showing the RiverbankTeaRooms from the Login on success, test the login result in your Program.Main and then show the RiverbankTeaRooms or any error message.

Add the following to Login :

    public bool Success { get; private set; }

    public static bool Authenticate()
    {
        var login = new Login();
        login.ShowDialog();

        return login.Success;
    }

And update your Enter_Click :

    private void Enter_Click(object sender, EventArgs e)
    {
        try
        {
            // Search through database through dr[1] (Table 2) for matching string.
            foreach (DataRow dr in dra)
            {
                if (dr[1].ToString() == Code.Text)
                {
                    Success = true;
                    break;
                }
            }
            if (!Success)
            {
                // Incorrect password.
                Code.Text = "Incor";
            }
            else
            {
                this.Close();
            }
        }
        catch
        {
            // Error, most likely with Database.
            Code.Text = "Error";
        }
    }
}

And just use the Authenticate method :

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new RiverbankTeaRooms() { SignedIn = Login.Authenticate() });
}

If you need to authenticate again inside the RiverbankTeaRooms , you can do it like this :

if (Login.Authenticate())
{
    // do stuff...
}
else
{
    // show error, or stop the user
}

To answer the titular question, simply pass the Login instance to the RiverbankTeaRooms object:

RiverbankTeaRooms main = new RiverbankTeaRooms(this);

//In other form
Login myPrivateLoginReference;
public RiverBanksTeaRoom(Login loginForm)
{
   myPrivateLoginReference = loginForm;
}

For your specific case, there are other approaches, such as raising an event from main that would also work:

main.ShowLoginRequested += ShowLogin;

void ShowLogin()
{
   this.Show();
}

As an aside, please never store passwords as plaintext in a database, as it appears you are doing, you should always be comparing against a hash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM