1

I am developing an application which requires loggging in.

I've developed the following forms: - frmMain - frmLogon

Form main launches when bootstrapping the windows forms application. In the "Shown" event of form main the FrmLogon form is shown as a dialog.

However when automatically setting the DialogResult to OK the form won't close, the program only works when manually hitting the "Logon" button, which triggers the exact same functionality.

Ive tried to Close() the form logon, but this leaves me with an System.ObjectDisposedException.

Any suggestions?

FrmMain.CS

private void OnFormShown(object sender, EventArgs e)
    {
        OnClickMenuLogon(sender, e);
    }

private void OnClickMenuLogon(object sender, EventArgs e)
        {
            if (IsLoggedOn())
            {
                G.LogOff();
                User = null;
                OnLoggedOff();
            }
            else
            {
                FrmLogon logon = new FrmLogon(G, true);
                DialogResult result = logon.ShowDialog();
                if (result == DialogResult.OK)
                {
                    User = logon.User;
                    _hostName = User.Name + " @ " + (String.IsNullOrEmpty(logon.HostName) ? Environment.MachineName : logon.HostName);
                    OnLoggedOn();
                }
            }
        }

FrmLogon.CS

private void OnLogOnSuccess(object sender, LoggedOnEventArgs e)
    {
        tbStatus.Text = $"[{DateTime.Now.ToString("HH:mm:ss")}]: Successfully logged on.\r\n" + tbStatus.Text;
        User = _g.LoggedUser;
        HostName = tbHost.Text;
        DialogResult = DialogResult.OK;
    }

Edit: When using

   this.DialogResult = DialogResult.OK;
this.Close();

the following exception occurs: Exception screenshot

Stan Hurks
  • 1,844
  • 4
  • 14
  • 25
  • Instead of DialogResult = DialogResult.OK; try this.Close(); – Stephen Wilson May 08 '17 at 14:01
  • @StephenWilson not correct according to [Using DialogResult Correctly](http://stackoverflow.com/questions/16846573/using-dialogresult-correctly) – stuartd May 08 '17 at 14:02
  • @StephenWilson this.Close will return him DialogResult.Cancel – Samvel Petrosov May 08 '17 at 14:05
  • @stuartd the login is asynchronous, the eventhandler is configured in the FrmLogon constructor. Whenever a logon is successfull the function will be called. In the constructor the application makes an attempt to log on automatically, which causes the problem somehow. Whenever hitting the "log on" button inside the form instead of doing so programatically the same logon functionality does indeed work. – Stan Hurks May 08 '17 at 14:34
  • @stuartd problem was that the logon attempt was made in FrmLogon constructor, after making an event for the shown event and doing the logon attempt there for this form the functionality works, thanks for the support! – Stan Hurks May 08 '17 at 14:38
  • 1
    Do not put (SOLVED) in your titile, undo your last edit, and if you solve your own problem post an answer and accept it once the timer allows you to in two days. – Scott Chamberlain May 08 '17 at 14:47
  • @ScottChamberlain Excuse me, I'm new to posting questions here, changed it. – Stan Hurks May 08 '17 at 14:51

2 Answers2

1

Problem is solved, the attempt to logon was made in the FrmLogon's constructor which caused the DialogResult to be set before the form was initialized. After implementing the "Shown" event and calling the functionality from there in FrmLogon the problem was solved. Thank you all.

Stan Hurks
  • 1,844
  • 4
  • 14
  • 25
0

Instead of just using

DialogResult = DialogResult.OK;

Use

this.DialogResult = DialogResult.OK;
this.Close();

this.Close() will close your second form and return it's current DialogResult.

UPDATE 1

Other way is to add some invisible button to the Dialog Form, set it as AcceptButton and perform click on it in this way:

    Button bt = new Button();
    bt.Click += new EventHandler((sender1,e1)=> {
        this.DialogResult = DialogResult.OK;
    });
    bt.FlatStyle = FlatStyle.Flat;
    bt.FlatAppearance.BorderColor = BackColor;
    bt.FlatAppearance.MouseOverBackColor = BackColor;
    bt.FlatAppearance.MouseDownBackColor = BackColor;
    this.Controls.Add(bt);
    this.AcceptButton = bt;
    bt.PerformClick();
Samvel Petrosov
  • 7,580
  • 2
  • 22
  • 46
  • It shouldn't be necessary, which is the point of the question - as the docs say _"If the form is displayed as a dialog box, setting this property with a value from the DialogResult enumeration sets the value of the dialog box result for the form, hides the modal dialog box, and returns control to the calling form."_ – stuartd May 08 '17 at 14:09
  • @stuartd yes it's so in case that you have set AcceptButton and CancelButton as it is shown in the MSDN example https://msdn.microsoft.com/en-us/library/system.windows.forms.form.dialogresult(v=vs.110).aspx – Samvel Petrosov May 08 '17 at 14:12
  • I have already tried this, this leaves me with the following exception:"System.ObjectDisposedException: 'No access to a deleted object.'", the deleted object being the FrmLogon logon object. – Stan Hurks May 08 '17 at 14:12
  • @StanHurks can use share screenshot of the exception I am sure it's not from the form closing. I have tried it with empty forms and it's working as it must. – Samvel Petrosov May 08 '17 at 14:14
  • @StanHurks also can you share your OnLoggedOn() function – Samvel Petrosov May 08 '17 at 14:17
  • @S.Petrosov I have put the screenshot in the article, the OnLoggedOn() function isn't called yet when the exception occurs. It appears that the FrmLogon logon object gets disposed by using this.Close() in the FrmLogon form. – Stan Hurks May 08 '17 at 14:22
  • @StanHurks try the second way which I have added to my answer – Samvel Petrosov May 08 '17 at 14:31
  • @S.Petrosov Thanks for the support, I've figured out that the form did not respond to the DialogResult.OK because the logon attempt was made in the constructor of this form and it should've been in the "shown" event belonging to the FrmLogon form, silly mistake.. – Stan Hurks May 08 '17 at 14:39