0

アプリケーションには2つのフォームがあります。1つは新しい接続を作成するためのもので、もう1つは接続名を保持するメニューを保持するメインフォームです。

ここに画像の説明を入力してください

フォームの下に新しい接続を作成し、frmNewConnection生成されたメニュー項目をクリックしようとすると、プログラムを再度開いたときのようにテストメッセージが表示されません。

メインフォームには、次のパブリックサブがあります。

メインフォームであるfrmMain

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

アプリケーションを再起動しない限り、そのコードは実行されません。新しく生成されたメニュー項目をクリックすると、正常に機能します。しかし、アプリケーションをロードして[新しい接続]メニュー項目をクリックして新しい接続を作成し、[接続]メニューの下でクリックしようとすると、何も起こりません。[テスト]メッセージボックスが表示されません。

frmNewConnection Acceptボタンの下に次のコードがあります。これにより、接続の名前が「接続」メニューに保存されます。

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 に答える