0
votes

I'm really confused so I'm hoping someone can help me out here. I'm working on a programming assignment for uni but there's one part that's really been bugging me and I can't move on until it is fixed. I have created two classes. The problems in each are shown here:

class Login : Form1
{
    Form1 f = new Form1();

    public void LoginCorrect()
    {
        Form1.attempts = 3;
        MessageBox.Show("Correct Credentials Entered!");

        f.loginScreenVar = false;
        f.mainScreenVar = true;
        f.ChangeScreen();
    }
 }


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public void ChangeScreen()
    {
        //Login Screen
        txtUsername.Visible = loginScreenVar;
        txtPassword.Visible = loginScreenVar;
        btnLogin.Visible = loginScreenVar;
        lblLoginCaption.Visible = loginScreenVar;
        lblUsername.Visible = loginScreenVar;
        lblPassword.Visible = loginScreenVar;
        //Main Screen
        lblWelcomeUser.Visible = mainScreenVar;
        btnViewDetails.Visible = mainScreenVar;
        btnViewAccounts.Visible = mainScreenVar;
        btnLogout.Visible = mainScreenVar;

        MessageBox.Show(loginScreenVar.ToString());
    }
}

I have some controls on screen in my design which consist of text boxes, labels, and buttons, and these are meant to show and hide at diffferent times. I have created some booleans which can be set to true and false which will also set the visibility of these controls to true and false.

My problem is when accessing ChangeScreen() from my Login class, for some reason the controls don't hide when they're meant to. I've literally got a message box in the ChangeScreen() method which outputs the result of 'loginScreenVar' and this is false. Please can someone tell me why my 'Login Screen' controls are NOT hiding even though 'loginScreenVar' = false.

Another thing to note is when calling this code from a button in the Form1 class, it does work. However, due to the brief of my assignment I need to use multiple classes.

I really hope this isn't a bug and someone can help me here because I literally can't move on until this is fixed, thanks!

3
It seems that you have not a clear understanding of a fundamental OOP concept. Inside the Login class you create a NEW instance of Form1. This is not the same instance used by the Login form class. Is is a totally different instance with its own copy of every textboxes and other controls. You set the control's values for this instance not for the Login instance created elsewhere in your project. To understand better just add a f.Show() after the call to f.ChangeScreen(); - Steve
The code you've posted won't do anything at all. You need to post a minimal complete verifiable example. But my guess is you're trying to post information from your Login form to your Form1. That's not what you're doing; you're creating a Form1 inside your Login form that you never display, then discard it immediately. You probably want to Pass values between forms. - Dour High Arch
It'd be helpful if you told us your exact assignment (or at least the relevant parts) to get a better solution if needed. - TimB

3 Answers

0
votes

The issue is that, as noted in the comments, you create a new instance of Form1.

A whole new object, with own states.

Why can't I see this new instance? - well, if you did f.show() THEN you'd see it.

As it stands, you're still looking at the old instance.

So, what you need is a publicly accessible instance of Form1 which your two classes access, without creating a new instance.

OR

you could also work with two different windows. For example:

Form1_loaded(object sender, EventArgs e)
{
    LoginWindow lw = new LoginWindow();
    var result = lw.ShowDialog();
    if(result == DialogResult.Cancel)
    {
        Application.Quit();
    }
}

Let's assume you have a button for login. When clicked, it checks whether password and user name are correct. If not, the incorrect count gets increased by one. If the incorrect count is >= 3, then you just close the LoginWindow. (Default DialogResult is DialogResult.Cancel). The code might look like this:

LoginBtn_Click(object sender, EventArgs e)
{
    if(UserNameInput.Text == userName && PasswordInput.Text == password)
    {
        failedAttempts = 0;
        this.DialogResult = DialogResult.OK;
        this.Close();
    }
    else
    {
        failedAttempts++;
        if(failedAttempts >= 3)
        {
            MessageBox.Show("Wrong password. Shutting down the application...");
            this.Close();
        }
        else
        {
            MessageBox.Show("Wrong password. " + (3-failedAttempts) + " tries left.");
        }
    }
}

This way, if login isn't successful, app quits. Otherwise the main screen appears.

Note: This is a basic solution. In a more complex app, you'd want more sophisticated output (not hard-coded strings) and comparisions using VariableName.Equals();

0
votes

Let's keep it simple (and in the style you've started) for now:

public partial class Form1 : Form //Change the default "form1" "Button1" etc names as soon as possible
{
    private bool loginScreenVar = true; //when naming booleans, use "truth test" sounding names like isLoginScreenMode
    private bool mainScreenVar = true;

    public Form1() //this is a constructor, a method that is always called when a new instance of this object is created
    {

        InitializeComponent();

        //use the constructor to set things up
        loginScreenVar = true;
        mainScreenVar = false;
        ChangeScreen();//make sure loginscreen is showing
    }

    public void ChangeScreen()
    {
        //Login Screen
        txtUsername.Visible = loginScreenVar;
        txtPassword.Visible = loginScreenVar;
        btnLogin.Visible = loginScreenVar;
        lblLoginCaption.Visible = loginScreenVar;
        lblUsername.Visible = loginScreenVar;
        lblPassword.Visible = loginScreenVar;
        //Main Screen
        lblWelcomeUser.Visible = mainScreenVar;
        btnViewDetails.Visible = mainScreenVar;
        btnViewAccounts.Visible = mainScreenVar;
        btnLogout.Visible = mainScreenVar;

        MessageBox.Show(loginScreenVar.ToString());
    }

    //call this method when the login is correct
    public void LoginCorrect()
    {

        loginScreenVar = false;
        mainScreenVar = true;
        ChangeScreen();
    }

    //double click your login button in the forms designer to add this click event handler
    public void LoginButton_Clicked(object sender, ClickEventArgs e){
        if(txtUsername.Text == "user" && txtPassword.Text == "pass"){
            LoginCorrect();
        } else {
            MessageBox.Show("Login incorrect");
        }
    }
}

Forget the class Login:Form stuff unless you're really trying to explore object instantiation and making your own classes for things. Your Form1 will be on show when your app starts, do all the logic inside it

0
votes

A better way to change screens in winforms is by creating two separate panels each one contains the desired controls to be shown and hide so that you can switch between them

Code example:

Form1_loaded(object sender, EventArgs e)
{
    LogInPanel.Visible=true;
}
private void ConnectBtn_Click(object sender, EventArgs e)
{
    // Do your checking here
   //        IF conditions met
   MainPanel.Visible=true;
}
private void DisconnectBtn_Click(object sender, EventArgs e)
{
    // Do your checking here
   //        IF conditions met
   LogInPanel.Visible=true;
}

If you want to keep you methadologie make sure your program.cs runs Login class instead of Form1 class