【问题标题】:Allow custom events on main form?允许主窗体上的自定义事件?
【发布时间】:2014-08-04 02:49:51
【问题描述】:

假设我有 foo 类:

Public Class foo
End Class

现在假设我有一个外部调用的函数:

Public Class foo
  Public Sub my_sub ()
  End Sub
End Class

如果有时我希望其他函数能够知道何时调用此函数并且满足某些条件怎么办?没问题,我会创建一个事件:

Public Class foo
  Event something_happened ()
  Public Sub my_sub ()
    If some_condition_is_met Then
      RaiseEvent something_happened ()
    Else
     'Do Nothing!
   End If
 End Sub

结束类

现在,当我创建一个类的实例时,我必须这样声明它:

Dim WithEvents my_foo As foo

好吧,当我在表单类中创建自己的事件以供其他类接收时,VB 会抱怨,因为表单的实例未声明为:

WithEvents

考虑到我没有在代码中声明实例,因此无法插入,如何使表单支持添加其他应用程序可以接收的事件:

With Events

我是更改声明它的自动生成代码还是什么?

【问题讨论】:

    标签: .net vb.net winforms class events


    【解决方案1】:

    阅读您的评论后,我想我明白了您的意思。请看这个:

    Public Class DesignerForm
        Public Event YourEvent()
    
        Private LC As ListenerClass
    
        Private Sub YourMethod()
            If True Then 'Your conditionals go here.
                RaiseEvent YourEvent()
            End If
        End Sub
    
        Private Sub DesignerForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            LC = New ListenerClass(Me)
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            YourMethod()
        End Sub
    End Class
    
    Public Class ListenerClass
        Private WithEvents DF As DesignerForm
    
        Public Sub New(ByRef DF As DesignerForm)
            Me.DF = DF
        End Sub
    
        Private Sub YourEventExternalHandler() Handles DF.YourEvent
            'Here you handle YourEvent outside your Main Form Class.
        End Sub
    End Class
    

    您的主窗体类直接由 WFD 生成,并且您的类引用了它的运行时实例。在此示例中,当您单击 Button1 时,YourEvent 会在 ListenerClass 中触发和处理。

    附: 只有当您至少可以从 ListenerClass 中获得 DesignerForm 类的某种可见性(任何类型:项目引用、动态加载等)时,所有这些才是有效的,否则您甚至无法引用它,您将不得不使用常见的进程间通信机制。

    【讨论】:

      【解决方案2】:

      WithEvents 关键字并不神奇地意味着一个对象会引发事件或其他对象可以处理它们。 WithEvents 关键字具体表示可以在Handles 子句中使用变量。就是这样。

      如果一个对象引发事件,那么它就会引发事件。如果您想处理这些事件并且该对象未分配给声明为WithEvents 的变量,那么您可以使用AddHandler 语句将方法注册为事件的处理程序。当您不想再处理该事件时,您可以使用RemoveHandler。

      请注意,虽然语法略有不同,但这是在 C# 中处理事件的唯一方法;没有等同于 WithEvents 和 Handles。

      【讨论】:

        【解决方案3】:

        我不知道我是否理解了这个问题,但是,这个(非常简化的)示例怎么样?

        Public Class YourForm
            Inherits System.Windows.Forms.Form
        
            Public Event E1()
        
            ' In this example event may be fired on form loading.
            Public Sub YourForm_Load() Handles MyBase.Load 
                If True Then ' You may use your conditionals here.
                    RaiseEvent E1()
                End If
            End Sub
        End Class
        
        Public Class AnotherForm
            ' You may not need to inherit from Form
            Inherits System.Windows.Forms.Form
        
            Dim WithEvents F1 As YourForm
        
            Public Sub New()
                MyBase.New()
        
                F1 = New YourForm()
            End Sub
        
            Public Sub YourFormLoadingHandler() Handles F1.E1
                'Handle your event here
            End Sub
        End Class
        

        只要将 YourForm 设置为由 AnotherForm 加载,您就有机会在第二类中处理该事件。

        我可能还是没听懂这个问题。

        问候。

        【讨论】:

        • 我的问题主要涉及这样一个事实,即如果未使用关键字“WithEvents”声明实例,则 Visual Basic 将不允许处理属于对象实例的事件。如果我使用 Visual Studio 设计器制作的设计器表单需要有事件来接收自定义类,考虑到 VB 需要使用关键字声明的具有已处理事件的对象,我怎么能允许这样做?我没有声明设计器表单,因此无法添加关键字,但我需要对象具有可用事件。我不太明白你的回答。
        • 没关系,有了这个评论,我更好地理解了你的问题。请稍等,我格式化答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多