22 Stimmen

Wie deklariert man Lambda-Event-Handler in VB.Net?

Ich glaube, der folgende VB.Net-Code entspricht dem vorangehenden C#-Code; jedoch schlägt der VB.Net-Test fehl - die Ereignisbehandlungslambda wird nie aufgerufen.

Was ist los?

VB.Net-Version - scheitert:

 _
Public Class TestClass
     _
    Public Sub EventTest()
        Dim eventClass As New EventClass
        Dim eventRaised As Boolean = False
        AddHandler eventClass.AnEvent, Function() (eventRaised = True)
        eventClass.RaiseIt()
        Assert.IsTrue(eventRaised)
    End Sub    
End Class

Public Class EventClass
    Public Event AnEvent()
    Public Sub RaiseIt()
        RaiseEvent AnEvent()
    End Sub

C#-Version - besteht:

[TestFixture]
    public class TestClass
    {
        [Test]
        public void EventTest()
        {
            var eventClass = new EventClass();
            var eventRaised = false;
            eventClass.AnEvent += () => { eventRaised = true; }; 
            eventClass.RaiseIt();
            Assert.IsTrue(eventRaised);
        }
    }

    public class EventClass
    {
        public delegate void EventHandler();
        public event EventHandler AnEvent;
        public void RaiseIt()
        {
            AnEvent();
        }
    }

25voto

svick Punkte 224493

Für diejenigen, die diese Frage jetzt finden: Seit Visual Basic 2010 (VB 10.0) funktionieren anonyme Subs, sodass Sie etwas Ähnliches schreiben können:

Sub() eventRaised = True

18voto

Gareth D Punkte 875

Hinweis: Dies bezieht sich auf ältere Versionen von VB.net vor Visual Studio 2010 und VB.net 10

Der Unterschied besteht darin, dass in VB.Net ein Lambda-Ausdruck einen Wert zurückgeben muss, d.h. sie müssen Funktionen und keine Subroutinen sein. Der Lambda-Ausdruck eventRaised = true wird als boolescher Ausdruck interpretiert anstatt als Zuweisung, d.h. er wird zu false evaluiert anstatt auf true gesetzt zu werden.

Weitere Details auf MSDN.

Ich glaube nicht, dass das in dem Beispiel verwendete c#-Muster für das Testen von Ereignissen in VB.Net ohne Einführung einer weiteren Funktion durchgeführt werden kann, z.B.

 _
Public Class Test
     _
    Public Sub EventTest()
        Dim eventClass As New EventClass
        Dim eventRaised As Boolean = False
        AddHandler eventClass.AnEvent, Function() (SetValueToTrue(eventRaised))
        eventClass.RaiseIt()
        Assert.IsTrue(eventRaised)
    End Sub

    Private Function SetValueToTrue(ByRef value As Boolean) As Boolean
        value = True
        Return True
    End Function

End Class

Public Class EventClass
    Public Event AnEvent()
    Public Sub RaiseIt()
        RaiseEvent AnEvent()
    End Sub

2voto

Denis Troller Punkte 7331

Um es kurz zu machen, im Moment können Sie das in VB nicht tun (es steht auf der Liste der Funktionen, die für das nächste Release in Betracht gezogen werden). Sie müssen eine deklarierte Methode und den AddressOf-Operator verwenden.

Das VB-Team hatte keine Zeit, anonyme Delegaten in die Sprache einzubeziehen (das ist es, was Sie technisch gesehen verwenden wollen, nicht ein Lambda-Ausdruck).

Lambda-Ausdrücke mussten sie implementieren, damit Linq tatsächlich funktioniert. Anonyme Delegaten werden von nichts benötigt (wären aber ziemlich nützlich). Ich vermute, sie haben mehr Zeit damit verbracht, Sachen wie Linq To XML und XML-Literale einzuschließen und weitere Abfrageoperatoren in die Syntax zu integrieren...

0voto

Ahmed_mag Punkte 195

WPF-Steuerelemente, die Popups haben, benötigen eine Instanz des WPF Application Objekts. In einer WPF-Anwendung wird dies automatisch erstellt. In einer WinForm-Anwendung ist das nicht der Fall. Aus diesem Grund muss dieses Objekt manuell erstellt werden. Die Anwendung muss auch so eingestellt werden, dass sie geöffnet bleibt, bis sie durch Code heruntergefahren wird, da sie sonst automatisch geschlossen wird, wenn die WinForm-Anwendungen feststellen, dass sie nicht mehr benötigt wird. Der folgende Code öffnet das Application-Objekt in einer WinForm und hält es geöffnet, bis es geschlossen ist. Das Herunterfahren des Application-Objekts beim Schließen der WinForm ist der empfohlene Ansatz.

Dim app As System.Windows.Application = New System.Windows.Application With {
            .ShutdownMode = Windows.ShutdownMode.OnExplicitShutdown
        }
        AddHandler Closed, Sub()
                               app.Shutdown()
                           End Sub

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X