2011-08-18 84 views
1

我有通過代碼(動態)生成的按鈕。我必須將一個事件(同樣)與他們聯繫起來。我使用AddHandler button.click, AddressOf mysub在Visual Basic .NET中的AddressOf

問題是,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 
+0

按鈕生成點擊,而不是字符串,請仔細考慮一下 –

+0

You didn 't understand ...看到現在我的場景 – Alph

+0

刪除最後一個參數 –

回答

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 lambda表達式

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

如果您使用Visual Studio的早期版本,它是一個有點困難,因爲你需要手動建立一個封閉。

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 button.Click AddressOf closure.OnClick

+0

+1這是在VB中執行此操作的常用方法... – gbianchi

+0

我添加了我的場景 – Alph

+0

@Alph你想傳遞給那個函數的字符串是什麼? – JaredPar

0

AddHandler操作不調用處理程序,以便它沒有意義的嘗試命令期間傳遞給它的變量。 AddHandler只是告訴框架,當事件引發時需要調用mysub方法。

UPDATE 您應該查看Button.CommandArgument屬性。這將允許你爲你的按鈕分配一個任意值,這個值將在你的事件處理程序中被訪問。由於該屬性屬於按鈕,因此只有當您想要傳遞的值不會爲每個按鈕更改時,這纔有所幫助。換句話說,如果每次按button1,您想要通過foo,這將工作。否則,它不會有幫助。

在Form.Load:

btn.CommandArgument = "foo"; 

在您的處理程序:

Button btn = (Button)sender; 
Console.Write(btn.CommandArgument); //foo 
+0

因此,我正在尋找AddressOf的替代方案。我不擅長VB。 – Alph

+0

替代什麼?得到一個沒有入口點地址的例程? – Martin

+0

我給了一個替代方案,但可能不是你所希望的。 – Jeff

0

我覺得這是一個什麼AddressOf確實,真的是誤會。

AddressOf只是將一個MEMORY ADDRESS存儲到一個函數或方法中。閱讀關於.NET委託,你會得到這個概念,但關鍵是要了解委託是:在.NET中用於存儲方法的MEMORY ADDRESSES的類型。只是。 委託變量是否存儲任何方法?不,沒有任何方法,只有簽名與委託聲明相符的方法。

然後你應該瞭解事件的概念,這是非常重視的代表,只是因爲一個事件需要知道什麼代表將處理它(誰是事件處理程序,這是一個代表)

現在你提到了一些無法將參數傳遞給AddressOf的東西。這是你的誤解。因爲你直接越過存儲器地址的方法或功能不傳遞任何參數AddressOf,並且該方法或函數已經包含的參數按照其聲明。

所以,當你發現是這樣的:

AddHandler button.click, AddressOf mysub 

你告訴編譯器是:「我知道那個叫按鈕按鈕觸發事件的能力上點擊它的時候所以我想處理(委託該發生的動作)這個單擊事件與方法mysub無論它是生活在記憶..」

mysub是單擊按鈕時將執行的方法。

你想知道傳遞什麼參數或如何傳遞參數。您不會傳遞任何參數,因爲它將是傳遞這些參數的按鈕單擊事件。您可以只處理mysub方法從按鈕接收的參數。

你怎麼知道什麼參數mysub應該接受來自按鈕?因爲它們必須是委託定義中定義的那些。請記住,我們說,代理變量不內存地址存儲的任何方法,但只有方法的簽名附加到按鈕事件點擊委託的定義

所以還是按鈕的定義相匹配事件,你會發現它使用委託類型。查看該委託的簽名,您將確切知道該委託存儲的方法的參數類型。

然而,良好做法說,事件應該被附加到代表們的簽名(該方法的它可以存儲簽名)包含2個參數:

  • 第一個參數是發送者,即產生該事件的對象。所以它是一個

    sender as Object 
    
  • 第二個參數是一個包裝的任何其它參數包含更多信息的一個對象,該對象必須是一個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 

所以在這如果你會說編譯器:「當按鈕命名按鈕生成一個click事件我要你執行這個匿名的(它沒有名字)方法。而且我知道按鈕的click事件傳遞了2個參數,請將第一個參數放在我的sender變量中,第二個參數放在EventArgs變量中「