locked
vb.net equivalent RRS feed

  • Question

  • Hi

    What is the vb.net equivalent for the following c# snippet?

    void Editor_Init(object sender, EventArgs e,WebControl baseEditor)
    {
         ASPxWebControl editor = (ASPxWebControl)sender;
         editor.Init -= new EventHandler((s, args) => Editor_Init(s, args, baseEditor));
    }

    Thanks

    Regards



    • Edited by Y a h y a Thursday, April 3, 2014 2:28 PM
    Thursday, April 3, 2014 2:27 PM

Answers

  • Reed, Dave

    I would think the third argument is an optional argument. The signature can then work.

    ----------------------------

      When using Addhandler, with the lambda in line, 

    AddHandler Me.SomeEvent, Sub(s as object, e as eventargs) ...

     then, the event becomes is impossible to remove from the collection. As this code show if you try it

    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            AddHandler Button1.Click, Sub(s, arg) Beep()
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim Lambda = Sub(s, arg) Beep()
            RemoveHandler Button1.Click, Lambda
        End Sub
    
    End Class

    The reason is that the lambda installed in the event collection and the lambda you created to remove it are two different objects. (Even if they look, code wise, identical)

    therefore

    RemoveHandler Me.SomeEvent, Sub(s as object, e as eventargs) ...

    will never remove nothing.

    The proper way would be to do it like this

    Public Class Form1
    
        Private Lambda As EventHandler = Sub(s, e) Beep()
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            AddHandler Button1.Click, Lambda
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    
            RemoveHandler Button1.Click, Lambda
        End Sub
    
    End Class

    (  NOTE: This is also true in C#)



    Thursday, April 3, 2014 4:03 PM

All replies

  •     Private Sub Editor_Init(ByVal sender As Object, ByVal e As EventArgs, ByVal baseEditor As WebControl)
            Dim editor As ASPxWebControl = DirectCast(sender, ASPxWebControl)
            Dim lambda = Sub(s, args) Editor_Init(s, args, baseEditor)
            RemoveHandler editor.Init, lambda
        End Sub

    Are you sure you need to remove the event wireup here?  It would seem to make more sense to add it.  Anyway, for some reason VB does not allow combining RemoveHandler with a lambda (this seems very odd) - you have to break it out into two statements.

    If it were an event wireup instead, then you would have the following in VB:

    Private Sub Editor_Init(ByVal sender As Object, ByVal e As EventArgs, ByVal baseEditor As WebControl)
    	 Dim editor As ASPxWebControl = DirectCast(sender, ASPxWebControl)
    	 AddHandler editor.Init, Sub(s, args) Editor_Init(s, args, baseEditor)
    End Sub


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Instant C# - VB to C# Converter
    Instant VB - C# to VB Converter




    Thursday, April 3, 2014 2:39 PM
  • @Dave:

    I've seen web app examples like this before.  Leaking memory via event handlers is a common problem in web apps and one solution I've seen is to blindly unregister dynamic handlers before registering them.  This covers reentrant code without actually coding for it (or tries to anyway; may or may not actually be enough to prevent the issue).

    What's really strange about this particular code is the non conformant event handler signature... that baseEditor instance should be a member of a custom eventargs instance (at least, one would think).  This might be a case where a C# translation is not appropriate and the solution should be refactored into VB.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Thursday, April 3, 2014 3:02 PM
  • Reed, Dave

    I would think the third argument is an optional argument. The signature can then work.

    ----------------------------

      When using Addhandler, with the lambda in line, 

    AddHandler Me.SomeEvent, Sub(s as object, e as eventargs) ...

     then, the event becomes is impossible to remove from the collection. As this code show if you try it

    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            AddHandler Button1.Click, Sub(s, arg) Beep()
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim Lambda = Sub(s, arg) Beep()
            RemoveHandler Button1.Click, Lambda
        End Sub
    
    End Class

    The reason is that the lambda installed in the event collection and the lambda you created to remove it are two different objects. (Even if they look, code wise, identical)

    therefore

    RemoveHandler Me.SomeEvent, Sub(s as object, e as eventargs) ...

    will never remove nothing.

    The proper way would be to do it like this

    Public Class Form1
    
        Private Lambda As EventHandler = Sub(s, e) Beep()
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            AddHandler Button1.Click, Lambda
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    
            RemoveHandler Button1.Click, Lambda
        End Sub
    
    End Class

    (  NOTE: This is also true in C#)



    Thursday, April 3, 2014 4:03 PM
  • Thanks Crazypennie - that makes sense to me.

    So the original C# code was probably not doing what it was intended to do and the VB version I gave was equivalent but also not serving the intended purpose.


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Instant C# - VB to C# Converter
    Instant VB - C# to VB Converter

    Thursday, April 3, 2014 4:07 PM
  • For some reason I thought there was a way C# handled this when VB could not, but you are right, this code just doesn't do what it is intended to do.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Thursday, April 3, 2014 4:40 PM
  • On the same lines as Crazypennie the following can not be removed

    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            AddHandler cmdClose.Click,
                Sub()
                    Close()
                End Sub
    
            Controls.OfType(Of Control).ToList.ForEach(
                Sub(x)
                    If TypeOf x Is TextBox OrElse TypeOf x Is Label Then
                        AddHandler x.Click,
                            Sub(s As System.Object, a As System.EventArgs)
                                CType(s, Control).Visible = False
                            End Sub
                    End If
                End Sub)
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.

    Thursday, April 3, 2014 7:39 PM
  • Well, there is always a way to remove anything

    Just posting this as it is an interesting dig inside the framework 

    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            AddHandler Button1.Click,
              Sub()
                  Beep()
              End Sub
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim FI_EventClick As Reflection.FieldInfo = GetType(Control).GetField("EventClick", 32 Or 8) 'Non-Public Static
            Dim oClick As Object = FI_EventClick.GetValue(Button1) 'This is the Key for the Event Click in the EventHandlerList
            Dim ComponentType As Type = GetType(System.ComponentModel.Component)
            Dim FI_Events As Reflection.FieldInfo = ComponentType.GetField("events", 32 Or 4) 'Non-Public Instance
            Dim Events As System.ComponentModel.EventHandlerList 
            Events = FI_Events.GetValue(Button1) 'This is the Button1 EventHandlerList
            Dim Handlers As EventHandler = Events.Item(oClick) 'This is the Click event delegate
            Dim InvList() As [Delegate] = Handlers.GetInvocationList ' This is the delegate invocation list for the Click event
            For Each method As [Delegate] In InvList
                If method.Method.Name.Contains("Lambda$") Then
                    RemoveHandler Button1.Click, method ' Remove the Lambda handler from the event
                    Exit Sub
                End If
            Next
        End Sub
    
    End Class



    • Edited by Crazypennie Thursday, April 3, 2014 9:16 PM 321654
    Thursday, April 3, 2014 9:00 PM
  • That's interesting, but I don't think you can reliably find the exact lambda you're looking for if there were more than one wired to the event.

    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Instant C# - VB to C# Converter
    Instant VB - C# to VB Converter

    Thursday, April 3, 2014 9:12 PM
  • Very true and was tempted to toss a similar peice of code out that does the same thing but thought better of it.

    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.

    Thursday, April 3, 2014 9:21 PM
  • Very true Dave.

        Those lambda method will be named 

             _Lambda$__1       _Lambda$__2   etc ... 

    So, it would be required to know the order they were added to the event to be able to select one if there was more than one

    Thursday, April 3, 2014 9:27 PM
  • Hi

    Here is the accompanying 'add handler' c## code.

    void editModeTemplate_CustomCreateCellControl(object sender, DevExpress.ExpressApp.Web.Editors.CustomCreateCellControlEventArgs e)
            {
                if (e.PropertyEditor.Editor is ASPxWebControl)
                {
                    e.PropertyEditor.Editor.Init += new EventHandler((s, args) => Editor_Init(s, args, e.PropertyEditor.Editor));
                }
                else if (e.PropertyEditor is ASPxLookupPropertyEditor)
                {
                    ASPxLookupPropertyEditor editor = e.PropertyEditor as ASPxLookupPropertyEditor;
                    editor.DropDownEdit.DropDown.Init += new EventHandler((s, args) => Editor_Init(s, args, e.PropertyEditor.Editor));
                }
                
            }


    How does vb.net code work in this case especially when having to accommodate WebControl baseEditor and e.PropertyEditor.Editor parameters in remove handler and add handler respectively?

    Thanks

    Regards






    • Edited by Y a h y a Thursday, April 3, 2014 11:41 PM
    Thursday, April 3, 2014 11:37 PM
  • See my 'AddHandler' example in my first reply.

    This C# code has the problem pointed out by Crazypennie - the "-=" code to remove the event handler methods is just wrong - it will have no effect.

    See Crazypennie's suggestion for correcting this code by setting a field lambda.


    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Instant C# - VB to C# Converter
    Instant VB - C# to VB Converter

    Thursday, April 3, 2014 11:49 PM
  • Hi,

    Since we haven't heard from you for a long time, I temporarily close this case. I mark useful reply as answer. If you have any concerns, please free feel to reopen it or submit a new question.

    Thanks for your understanding.

    Best regards,
    Franklin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, April 10, 2014 10:17 AM