2012-02-04 28 views
9

De una forma u otra necesito vincular groupID (y otro entero) al botón que estoy agregando dinámicamente ... ¿alguna idea?AddressOf con el parámetro

Lo que puedo hacer;

AddHandler mybutton.Click, AddressOf PrintMessage 

Private Sub PrintMessage(ByVal sender As System.Object, ByVal e As System.EventArgs) 
    MessageBox.Show("Dynamic event happened!") 
End Sub 

Lo que no puedo hacer, pero quiero;

AddHandler mybutton.Click, AddressOf PrintMessage(groupID) 

Private Sub PrintMessage(ByVal groupID as Integer) 
    MessageBox.Show("Dynamic event happened!" & groupID .tostring) 
End Sub 
+0

Ver http://stackoverflow.com/questions/13401246/how-to-pass-parameters-in-addhandler-using-vb-net –

Respuesta

29

No hay forma de hacerlo con AddressOf. Lo que estás buscando es una expresión lambda.

AddHandler myButton.Click, Function(sender, e) PrintMessage(groupId) 

Private Sub PrintMessage(ByVal groupID as Integer) 
    MessageBox.Show("Dynamic event happened!" & groupID .tostring) 
End Sub 
+1

Intenté esto con un Sub como se muestra arriba, y recibí un error de compilación en .NET 3.5: "La expresión no produce un valor". Al configurar mi delegado como una función que siempre devuelve verdadero, funcionó. ¿¿POR QUÉ?? – http203

+1

@ http203 este es el detalle de implementación de la semántica de la expresión lambda en 3.5. El soporte solo se agregó para el valor que devuelve lambdas y 'Sub' no devuelve un valor. Esto se relajó en versiones posteriores del lenguaje – JaredPar

0

Utilice la propiedad Etiqueta del botón.

Button1.Tag = someObject 

AddressOf obtiene la dirección de un método y, por lo tanto, no puede pasarle parámetros.

+4

Yo te aconsejo fuertemente contra el uso de la propiedad 'tag' de los controles .Es una pesadilla de mantenimiento; ni su nombre ni su sugerencia de tipo estático en el objeto al que se hace referencia. Si desea seguir esa ruta, una mejor alternativa sería derivar una subclase 'MyButton' de' Button' y agregar una propiedad nueva, apropiadamente nombrada y tipada, como 'GroupId', y luego usarla en lugar de' Tag'. – stakx

3

Usted puede crear su propia clase de botón y añadir todo lo que desea que

Public Class MyButton 
    Inherits Button 

    Private _groupID As Integer 
    Public Property GroupID() As Integer 
     Get 
      Return _groupID 
     End Get 
     Set(ByVal value As Integer) 
      _groupID = value 
     End Set 
    End Property 

    Private _anotherInteger As Integer 
    Public Property AnotherInteger() As Integer 
     Get 
      Return _anotherInteger 
     End Get 
     Set(ByVal value As Integer) 
      _anotherInteger = value 
     End Set 
    End Property 

End Class 

Puede acceder al botón de colando el sender

Private Sub PrintMessage(ByVal sender As Object, ByVal e As EventArgs) 
    Dim btn = DirectCast(sender, MyButton) 
    MessageBox.Show(_ 
     String.Format("GroupID = {0}, AnotherInteger = {1}", _ 
        btn.GroupID, btn.AnotherInteger)) 
End Sub 

Estas nuevas propiedades incluso se puede establecer en la ventana de propiedades (en Misc).

Los controles definidos en el proyecto actual aparecen automáticamente en la caja de herramientas.

+0

. Si no tiene la intención de utilizar las propiedades para otra cosa que no sea el acceso a un campo privado sin restricciones, puede omitir el getter y el setter. – haiyyu

+2

Todavía tengo VS 2008. –

0

Hay pocas maneras de hacerlo en función de la complejidad y la cantidad de parámetros requeridos. 1. Use Tag para agregar una estructura compleja 2. Herede la clase Button Button y agregue los valores como miembros de la clase y rellenelos antes de usarlos. Eso te da mucha más flexibilidad.

Si está utilizando la versión web 3. No puede agregarlo a la etiqueta, pero para valores simples, asígnelo al uso de índice .Attributes.Add ("nombre"). Esto se agrega a las etiquetas HTML y no al lado del Servidor. A continuación, puede usar el índice para acceder a una estructura del lado del servidor para sistemas complejos. 4. Use las sesiones para almacenar valores y almacenar la referencia de la sesión al atributo de nombre como se describe arriba (# 3).

0

Puede utilizar delegado, que muy claro para el seguimiento de código como:

Definir un delegado

Public Delegate Sub ControlClickDelegate(ByVal sender As Object, ByVal e As EventArgs) 

clase de botón personalizado

Public Class CustomButton 
    Inherits System.Windows.Forms.Button 
#Region "property delegate" 

    Private controlClickDelegate As ControlClickDelegate 

    Public Property ClickHandlerDelegate As ControlClickDelegate 
     Get 
      Return controlClickDelegate 
     End Get 
     Set(ByVal Value As ControlClickDelegate) 
      controlClickDelegate = Value 
     End Set 
    End Property 

#End Region 

    Public Sub RegisterEventHandler() 
     AddHandler Me.Click, AddressOf OnClicking 
    End Sub 

    Private Sub OnClicking(ByVal sender As Object, e As System.EventArgs) 
     If (Me.controlClickDelegate IsNot Nothing) Then 
      Me.controlClickDelegate(sender, e) 
     End If 
    End Sub 

End Class 

MainForm

Public Class MainForm 
    Public Sub New() 

     ' This call is required by the designer. 
     InitializeComponent() 

     ' Add any initialization after the InitializeComponent() call. 

     Me.CusButton1.ClickHandlerDelegate = AddressOf Me.btnClick 
     Me.CusButton1.RegisterEventHandler() 
    End Sub 

    Private Sub btnClick(ByVal sender As Object, ByVal e As EventArgs) 
     Me.TextBox1.Text = "Hello world" 
     End Sub 

End Class 
Cuestiones relacionadas