Arie
Arie

Reputation: 3593

Close form from second form

My first form is login form, when user correctly log in i am hiding login form and showing up second form. Now instead of hiding login form i want to close it from second form. I thought i will be able to do it but somehow i got troubles with it.

So far i did like this below.

I made interface which my FrmLogin implements:

 Public Class FrmLogin
        Implements ICloseLogin

Interface:

Public Interface ICloseLogin
    Sub Close()
End Interface

FrmLogin implementing interface:

Private Sub ICloseLogin_Close() Implements ICloseLogin.Close
        Me.Close()
    End Sub

Now i am passing FrmLogin (Me) to second form constructor:

Private Sub ShowMainForm()
        Dim FrmMain As New FrmMainMDI(Me)
        FrmMain.IsMdiContainer = True
        FrmMain.StartPosition = FormStartPosition.CenterScreen
        FrmMain.Show()
        'Me.Hide() 'not anymore
    End Sub

Second form:

Public Class FrmMainMDI

    Private closeloginfform As ICloseLogin

 Sub New(frmlogin As ICloseLogin)

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        closeloginfform = frmlogin
    End Sub

    Private Sub FrmMainMDI_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
        closeloginfform.Close()
    End Sub

and when i debug and when it comes to line: closeloginfform.Close() i suppose to see only FrmLogin to be closed, but all is closing somehow. Why?

For further discussion:

  Imports DataAccessLayer
        Imports FormsUtils
        Imports BusinessLayer
        Imports System.Data.SqlClient
        Imports System.Configuration
        Imports System.Reflection
        Imports System.IO
        Imports Microsoft.WindowsAPICodePack.Dialogs
        Imports Probix

        Public Class FrmLogin

            Private Property Form As New FormUtils
            Private Property DB As New Procs
            Private Property _login As String
            Private Property _password As String

            Private Sub btnLogin_Click(sender As System.Object, e As System.EventArgs) Handles btnLogin.Click
                CheckAccess()
            End Sub


            Private Sub btnClose_Click(sender As System.Object, e As System.EventArgs) Handles btnClose.Click
                Me.Close()
            End Sub

            Private Sub FrmLogin_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
                Try

                    DB.OpenConn()
                    If DB.conn.State = ConnectionState.Open Then
                        Call Form.InitCombo(CboLogin, "SELECT * from tbLogin", DB.conn, "Login", "Login")
                        Call Form.InitCombo(CboLanguage, "SELECT * from tbLanguage where Active = 1", DB.conn, "Language", "Id")
                        Lang.name = DirectCast([Enum].Parse(GetType(Lang.LangShortcut), CboLanguage.GetItemText(CboLanguage.SelectedItem)), Lang.LangShortcut)
                    Else
                        Logger.LogIt(Modules.FrmLogin.ToString & ":  " & Methods.FrmLogin_Load.ToString, WriteMsg.Write(IssueCode.SqlServerConnectionError_pl), Application.StartupPath & "\log.txt", False)
                        Application.Exit()
                    End If

                Catch ex As Exception
                   Logger.LogIt(ex.tostring)

                    Application.Exit()
                Finally
                    DB.CloseConn()
                End Try
            End Sub

             Private Sub CheckAccess()
    Try
        _login = CboLogin.SelectedValue
        _password = txtPassword.Text
        If Not String.IsNullOrEmpty(txtPassword.Text) And Form.WybranoCombo(CboLogin, "Zaznacz login") Then
            Dim strcon = New AppSettingsReader().GetValue("ConnectionString", GetType(System.String)).ToString()
            Using con As New SqlConnection(strcon)
                Using cmd As New SqlCommand("Select COUNT(*) FROM tbLogin WHERE Login = @Login And Password = @Password", con)
                    cmd.CommandType = CommandType.Text
                    cmd.Parameters.AddWithValue("@Login", _login)
                    cmd.Parameters.AddWithValue("@Password", _password)
                    con.Open()
                    Dim o As Integer = cmd.ExecuteScalar()

                    '--CREDENTIALS OK
                    If o > 0 Then
                        CboLogin.Hide()
                        txtPassword.Hide()
                        btnLogin.Hide()
                        Label1.Hide()
                        Label2.Hide()
                        Try
                        Catch ex As Exception
                            MsgBox(ex.ToString)
                            End
                        End Try
                        '--CREDENTIALS NOT OK !!
                    Else
                        MsgBox("Wrong credentials")
                    End If

                End Using
            End Using
        Else
            MsgBox("Write some password !!")
        End If
    Catch ex As Exception
        Logger.LogIt(Modules.FrmLogin.ToString & ":" & Methods.FrmLogin_Load.ToString, WriteMsg.Write(IssueCode.Unknown_pl) & " ------> EX-MESSAGE: " & ex.ToString, Application.StartupPath & " \log.txt", False)
        Return
    End Try
End Sub

            Public Sub taskDialog_Opened(sender As Object, e As EventArgs)
                Dim taskDialog As TaskDialog = TryCast(sender, TaskDialog)
                taskDialog.Icon = taskDialog.Icon
                If Not taskDialog.FooterIcon = TaskDialogStandardIcon.None Then
                    taskDialog.FooterIcon = taskDialog.FooterIcon
                End If
                taskDialog.InstructionText = taskDialog.InstructionText
            End Sub

        End Class

Module Program:

  Module Program
    Public Sub main()
        Application.EnableVisualStyles()

        Dim result As DialogResult
        Using frmL As New FrmLogin
            result = frmL.ShowDialog
        End Using

        If result = DialogResult.OK Then
            Dim FrmMainMDI As New FrmMainMDI()
            Application.Run(FrmMain)
        End If
    End Sub
End Module

Further discussion 2

Solved???: I've added line within CheckAccess() sub, this line:

Me.DialogResult = DialogResult.OK  

so this peace of code has been changed only:

...
  '--CREDENTIALS OK
                        If o > 0 Then
                            CboLogin.Hide()
                            txtPassword.Hide()
                            btnLogin.Hide()
                            Label1.Hide()
                            Label2.Hide()
                            Try
                                '*************************************
                                Me.DialogResult = DialogResult.OK       '<=========================================
                                '*************************************
                            Catch ex As Exception
                                MsgBox(ex.ToString)
                                End
                            End Try
                            '--CREDENTIALS NOT OK !!
                        Else
                            MsgBox("Wrong credentials")
                        End If

...

Upvotes: 0

Views: 146

Answers (1)

A less involved way to do this is to start your app from Sub Main and only start the app if the LogIn is correct. For this:

  1. Add a module to your App, and name it Program. Add a Public Sub Main to it
  2. Go to Project Properties and Uncheck Enable Application Framework
  3. Now, for the Startup Object, select "Sub Main"

You can actually name the module anything, "Program" is descriptive and the convention used in C#. Then the Sub Main code:

Public Sub Main()

    Application.EnableVisualStyles()

    Dim result As DialogResult
    Using frmL As New frmLogin
        result = frmL.ShowDialog
    End Using

    If result = DialogResult.OK Then
        frmMain = New MainFrm()
        Application.Run(frmMain)
    End If

End Sub

Now, your two forms don't even have to know about each other. The MainForm will not even exist if/when the login fails. Whatever overhead there is related to starting/Loading the MainForm is also delayed until (and unless) the log in passes.


Your login button would be something like this (depending on how many failed attempts are allowed):

Private Sub btnLogIn_Click(sender As Object, e As EventArgs) Handles btnLogIn.Click
    If IsValidUser(tbName.Text, tbPW.Text) Then
        DialogResult = Windows.Forms.DialogResult.OK
    Else
        If tries >= 3 Then
            DialogResult = Windows.Forms.DialogResult.Cancel
        Else
            tries += 1
            Exit Sub
        End If
    End If
    Me.Hide()
End Sub

Upvotes: 3

Related Questions