1

コードを使用して(動的に)生成されたボタンがあります。イベント(同じ)をそれらに関連付ける必要があります。私は使用しますAddHandler button.click, AddressOf mysub

問題は、mysub が文字列 ( mysub(string)) を取得することですが、AddressOf はルーチン内のパラメーターを受け入れません。これどうやってするの?AddressOf の代替も使用します。

Public Class Form1

   ...

   Private Sub mysub(ByVal sender As Object, ByVal e As System.EventArgs, ByVal str As String)
      ...
      ...
   End Sub

   ...

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

      ...

      While something
         ...
         Dim btn As New Button
         ...
         AddHandler btn.click, AddressOf mysub 'here the issue
      End While

      ...

   End Sub
End Class
4

3 に答える 3

6

次のシナリオがあるようです

Class MyClass
  Public button As Button

  Public Sub New() 
    AddHandler button.Click AddressOf MySub
  End Sub

  Public Sub MySub(p As String)

  End Sub

End Class

その場合は、いくつかのオプションがあります。最も簡単なのは、ヘルパーメソッドを使用することです。それをイベントハンドラーにしてから、MySub関数を呼び出します

  Public Sub New() 
    AddHandler button.Click AddressOf MyHelper
  End Sub

  Public Sub MyHelper(sender As Object, e As EventArgs)
    MySub(TheStringValue)
  End Sub

編集

OPと話し合った後、問題はForm1_Load関数からMySubメソッドにローカルを渡すことです。Visual Studio 2010を使用している場合、これを行う最も簡単な方法はSubラムダ式を使用することです

Dim theString = ...
AddHandler button.Click (Sub (sender, e) MySub(sender, e))

以前のバージョンのVisualStudioを使用している場合は、手動でクロージャーを作成する必要があるため、少し難しくなります。

Class Closure 
  Public TheForm as Form1
  Public TheString As String
  Public Sub OnClick(sender As Object, e As EventArgs)
    TheForm.MySub(sender, e)
  End Sub
End Class

...

' In Form1_Load
Dim closure As New Closure
closure.TheForm = Me
closure.TehString = get the string 

AddHandlerボタン。AddressOfclosure.OnClickをクリックします。

于 2011-08-18T18:28:08.303 に答える
0

AddressOf が実際に何をするのか、実際に何をするのかについて誤解があると思います。

AddressOf は単に MEMORY ADDRESS を と呼ばれる関数またはメソッドに格納するだけです。.NET デリゲートについて読めば概念は理解できますが、重要なのは、デリゲートがメソッドの MEMORY ADDRESSES を格納する .NET の型であることを理解することです。それだけ。デリゲート変数にはメソッドが格納されますか? いいえ、メソッドではなく、署名がデリゲートの宣言と一致するメソッドのみです。

そして、イベントの概念について学ぶ必要があります。これは、イベントがどのデリゲートがそれを処理するかを知る必要があるためです (誰が eventHandler で、これはデリゲートです)。

今、あなたは引数を AddressOf に渡すことができないと言いました。これはあなたの誤解です。メソッドまたは関数にメモリ アドレスを直接渡すため、引数を AddressOf に渡しません。そのメソッドまたは関数には、その宣言に従って既に引数が含まれています。

したがって、次のようなものを見つけた場合:

AddHandler button.click, AddressOf mysub

あなたがコンパイラに伝えていることは次のとおりです。記憶の中に生きている..」

mysub は、ボタンがクリックされたときに実行されるメソッドです。

どの引数を渡すか、または引数を渡す方法を考えていました。これらの引数を渡すのはボタン クリック イベントであるため、引数を渡さないでください。メソッド mysub がボタンから受け取るパラメーターを処理するだけです。

また、mysub がボタンから受け取る必要のあるパラメーターをどのように知るのでしょうか? それらはデリゲート定義で定義されたものでなければならないからです。デリゲート変数はどのメソッドにもメモリ アドレスを格納せず、ボタン イベントクリックに関連付けられたデリゲートの定義と署名が一致するメソッドにのみ格納すると述べたことを思い出してください。

したがって、Button イベントの定義に移動すると、デリゲート型が使用されていることがわかります。そのデリゲートのシグネチャを見ると、このデリゲート ストアが持つメソッドの引数の型が正確にわかります。

ただし、グッド プラクティスでは、Event は、署名 (格納できるメソッドの署名) に 2 つの引数が含まれる Delegates にアタッチする必要があるとされています。

  • 最初の引数は、イベントを生成したオブジェクトである送信者です。だからそれは

    sender as Object
    
  • 2 番目の引数は、他のパラメーターを詳細情報でラップするオブジェクトです。オブジェクトは EventArgs (またはそれを継承) である必要があります。

    e as EventArgs
    

具体的な答えとして。ボタンのクリックイベントを処理するメソッドのメモリアドレスを渡す代替手段が必要な場合は、単にメモリアドレスを渡さず、次のような関数の内容を持ちます。

AddHandler button.click, Sub (ByVal sender As Object, ByVal e As System.EventArgs, ByVal str As String)
  'do something here
   End Sub

この場合、コンパイラに次のように伝えます。最初の引数を送信者変数に入れ、2 番目の引数を EventArgs 変数に入れます」

于 2014-08-12T00:02:30.380 に答える
0

オペレーターはハンドラーを呼び出さないため、そのAddHandlerコマンド中に変数を渡そうとしても意味がありません。イベントが発生するたびにメソッドを呼び出す必要があることをAddHandlerフレームワークに伝えるだけです。mysub

更新Button.CommandArgumentプロパティ を調べる必要があります。これにより、イベント ハンドラーでアクセス可能なボタンに任意の値を割り当てることができます。プロパティはボタンに属しているため、渡す値がボタンごとに変わらない場合にのみ役立ちます。つまり、 を押すたびbutton1に を渡したい場合foo、これでうまくいきます。そうでなければ、役に立ちません。

Form.Load で:

btn.CommandArgument = "foo";

ハンドラーで:

Button btn = (Button)sender;
Console.Write(btn.CommandArgument); //foo
于 2011-08-18T18:33:05.713 に答える