0

我的应用程序中有两种表单,一种是创建新连接,另一种是主表单,其中包含带有连接名称的菜单。

在此处输入图像描述

当我在表单下创建一个新连接frmNewConnection并尝试单击生成的菜单项时,它不会像我重新打开程序时那样显示测试消息。

在主要形式中,我有以下公共子。

frmMain 是主要形式

Public Sub Connect_SubMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs)
  Messagebox.Show("Test")
End Sub

除非我重新启动我的应用程序,否则该代码永远不会执行,然后当我单击新生成的菜单项时它工作正常。但是,如果我要加载应用程序并单击“新建连接”菜单项并创建新连接,然后尝试在“连接”菜单下单击它,则没有任何反应,我没有收到“测试”消息框。

我在 frmNewConnection Accept 按钮下有以下代码,它将连接的名称保存到“Connections”菜单。

frmMain.menuConnections.DropDownItems.Add(ConnectionName, Nothing, AddressOf frmMain.Connect_SubMenuItem_Click) ' save to menu

我还有一个在以下位置执行的代码版本frmMain_load()

menuConnections.DropDownItems.Add(finalData(1).ToString, Nothing, AddressOf Connect_SubMenuItem_Click) ' save to menu

我的问题是,为什么在程序中生成新菜单项时不会出现测试消息,但是当我关闭程序并重新打开它时它会显示..

4

2 回答 2

1

如果您正在从另一个表单修改一个表单的控件,那么您可能会做错事。

您需要做的第一件事是控制您的程序启动。VB 有时会隐藏这一点。这将允许您捕获表单变量。然后,考虑重构一下。

一些 VB.NET 伪代码(我对这里泄露的任何 C# 表示歉意):

Class Program

   Private _appCtx As AppContext

   Sub Main()

      _appCtx = New AppContext()

      'perform whatever bootstrap logic you needed here, typically
      ' configuring and installing behaviors into the app context
      '
      '

      ' one single instace of your main form
      _appCtx.RootForm = New frmMain(); 'or better still, pass AppContext into the ctor 

      Application.Run(_appCtx.RootForm)

   End Sub

   'if you want to cheat a bit, include this getter to provide access to everyone
   'otherwise, pass the app context to those classes that require it
   Public Shared AppCtx() As AppContext
      Get
         return _appCtx
      End Get
   End Property


End Class

Public Class AppContext

   Public Property RootForm As Form

   Public Property Connections As Connections

   'other application-wide subsystems or data

End Class

Public Class Connections

   Public Event Changed As EventHandler

   Public Property Count As Integer

   'other properties including a getter for the child connection objects...

   Public Sub Add(newConn As Connection)
      'add to internal list then...
      If Changed IsNot Nothing Then
         Changed(this, EventArgs.Empty)
      End If
   End Sub

End Class

Public Class frmMain


   Sub Form_Load() 

      AddHandler AppCtx.Connections.Changed AddressOf(Connections_Changed)

   End Sub

   Sub Connections_Changed()
      'iterate the connections and refresh the menu
      'the menu gets refreshed without breaking encapsulation!
   End Sub

End Class

Public Class frmNewConnection 


   private sub Accept_Click()

      'do stuff to create a connection object

      'add to the current set of connections, this will broadcast to anyone who needs to know      
      AppCtx.Connection.Add(newConn)

   End Sub 

End Class

如果您不想使用域对象事件进行更新,这取决于您,但示例的第一部分显示了如何将启动表单捕获到一个变量中,然后您可以在程序代码中使用该变量。

于 2012-09-14T19:25:52.760 回答
0

将菜单项添加到菜单后,您需要为其添加处理程序:

Private Sub btnAddMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddMenuItem.Click
    Dim tsmi As New ToolStripMenuItem("Test")
    Me.MenuStrip1.Items.Add(tsmi)
    AddHandler tsmi.Click, AddressOf Me.TestMenu
End Sub

Private Sub TestMenu(ByVal Sender As Object, ByVal e As System.EventArgs)
    MessageBox.Show("Test Menu")
End Sub
于 2012-09-14T20:22:45.513 回答