【问题标题】:Close form from second form从第二个表格关闭表格
【发布时间】:2023-03-30 16:59:01
【问题描述】:

我的第一个表单是登录表单,当用户正确登录时,我会隐藏登录表单并显示第二个表单。现在,我不想隐藏登录表单,而是想从第二个表单中关闭它。我以为我能做到,但不知何故我遇到了麻烦。

到目前为止,我在下面这样做了。

我创建了我的 FrmLogin 实现的接口:

 Public Class FrmLogin
        Implements ICloseLogin

界面:

Public Interface ICloseLogin
    Sub Close()
End Interface

FrmLogin 实现接口:

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

现在我将 FrmLogin (Me) 传递给第二种形式的构造函数:

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

第二种形式:

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

当我调试时,当涉及到行时:closeloginfform.Close() 我想只看到 FrmLogin 被关闭,但一切都以某种方式关闭。为什么?

进一步讨论:

  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
    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

进一步讨论 2

已解决???:我在 CheckAccess() 子中添加了一行,这一行:

Me.DialogResult = DialogResult.OK  

所以这种代码的和平只被改变了:

...
  '--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

...

【问题讨论】:

  • 您为什么不将FrmMainMDI 设置为您的启动表单,然后在首次打开或用户未登录时抛出登录提示?我认为你的做法是错误的。
  • 首先你能解释一下为什么我的方法不起作用,然后你能解释一下你的意见吗?说实话我不明白。
  • but all is closing somehow 如果 FrmLogin 是启动表单,默认设置将在该表单关闭时结束应用程序。将 MDI 表单作为主表单,然后像往常一样显示/丢弃登录表单。或者将您的应用更改为从 Sub Main 开始
  • Plutonix 已经做到了,这将指导您更多(查看最佳答案)stackoverflow.com/questions/16634006/…。按照我建议的方式做会更好。
  • 项目 > 属性 > 应用程序选项卡 > 关闭模式,将其更改为“当最后一个表单关闭时”。顺便说一句,通过这些回旋毫无意义,您可以在调用 Show() 方法后简单地使用Me.Close()

标签: vb.net


【解决方案1】:

执行此操作的一种较少涉及的方法是从Sub Main 启动您的应用程序,并且仅在登录正确时启动应用程序。为此:

  1. 向您的应用程序添加一个模块,并将其命名为 Program。给它添加一个Public Sub Main
  2. 转到项目属性并取消选中Enable Application Framework
  3. 现在,对于 Startup Object,选择“Sub Main”

您实际上可以将模块命名为任何名称,“程序”是描述性的,并且是 C# 中使用的约定。然后Sub Main代码:

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

现在,您的两个表单甚至不必相互了解。如果/当登录失败时,MainForm 甚至将不存在。无论与启动/加载 MainForm 相关的开销如何,都会延迟到(并且除非)登录通过。


您的登录按钮将是这样的(取决于允许的失败尝试次数):

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

【讨论】:

  • 行为是,当用户正确登录时,FrmMainMDI 没有出现,FrmLogin 保持可见并关闭。请看一下主帖(进一步讨论是我的代码)
  • 我想我克服了上述评论中的问题,我在 CheckAccess 方法中添加了 Me.DialogResult = DialogResult.OK 行(检查主帖 - “进一步讨论 2”。它的工作但它是否正确并且可能像这个?
  • Plutonix 你能检查一下吗?
  • 是的,你需要在登录表单中设置DialogResult
  • 所以你能说我做对了吗?第二个问题如何把闪屏也放在那里?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多