Vb.net 如何在不向每个窗体添加代码的情况下为MDI子窗体设置事件?
我想在所有打开的子窗体上为某种类型的控件设置背景色。我有一个MDI父窗体,用于打开自身内的其他窗体。我不想为每个子表单添加代码,因为这将非常广泛。这将被用作应用程序的主题功能,因此我希望它能够根据主窗体中的逻辑自动更改背景颜色。是否有类似全局事件的东西可以触发所有Form.Load事件 到目前为止,我已经在父窗体中创建了一个事件,但它不适用于嵌套控件Vb.net 如何在不向每个窗体添加代码的情况下为MDI子窗体设置事件?,vb.net,winforms,event-handling,mdichild,mdiparent,Vb.net,Winforms,Event Handling,Mdichild,Mdiparent,我想在所有打开的子窗体上为某种类型的控件设置背景色。我有一个MDI父窗体,用于打开自身内的其他窗体。我不想为每个子表单添加代码,因为这将非常广泛。这将被用作应用程序的主题功能,因此我希望它能够根据主窗体中的逻辑自动更改背景颜色。是否有类似全局事件的东西可以触发所有Form.Load事件 到目前为止,我已经在父窗体中创建了一个事件,但它不适用于嵌套控件 Private Sub frmMain_MdiChildActivate(sender As Object, e As EventArgs) Ha
Private Sub frmMain_MdiChildActivate(sender As Object, e As EventArgs) Handles Me.MdiChildActivate
Dim ParentControl As frmMain = sender
Dim ChildControl = ParentControl.ActiveControl
If ChildControl IsNot Nothing Then
For Each FormControl As Control In ChildControl.Controls
If FormControl.GetType = GetType(GroupBox) Then
RemoveHandler FormControl.Paint, AddressOf PaintBorderlessGroupbox
AddHandler FormControl.Paint, AddressOf PaintBorderlessGroupbox
End If
Next
End If
End Sub
在父窗体中,保留已激活的所有子窗体的集合。然后可以遍历该集合并更改每个集合的相关控件属性
For Each ChildForm in MyCollection
ChildForm.TextBox.BackColor = Red
Next
当然:
- 父窗体必须可以访问子窗体控件
- 子窗体必须仍然存在(即未在中间关闭 时间)
- 无法检查子窗体闭包,因为您没有添加任何子窗体闭包 向子窗体发送代码以发出此类事件的信号
- 当您试图更改 已经关闭了
在
ChangeColour()
的子窗体设计中包含方法要容易得多,该方法是由事件触发还是直接调用是您的设计决策。并包含一种方法,用于在子窗体死亡时通知父窗体,以便它停止查找它。在父窗体中,保留已激活的所有子窗体的集合。然后可以遍历该集合并更改每个集合的相关控件属性
For Each ChildForm in MyCollection
ChildForm.TextBox.BackColor = Red
Next
当然:
- 父窗体必须可以访问子窗体控件
- 子窗体必须仍然存在(即未在中间关闭 时间)
- 无法检查子窗体闭包,因为您没有添加任何子窗体闭包 向子窗体发送代码以发出此类事件的信号
- 当您试图更改 已经关闭了
在
ChangeColour()
的子窗体设计中包含方法要容易得多,该方法是由事件触发还是直接调用是您的设计决策。并包含一种方法,用于在子窗体死亡时通知父窗体,以便它停止查找它。我可以通过使用form.mdichildactive
并基于事件和事件处理程序将事件添加到相应的控件中来完成此操作
Private Sub frmMain_MdiChildActivate(sender As Object, e As EventArgs) Handles Me.MdiChildActivate
Dim ParentForm As frmMain = sender
Dim ChildForm = ParentForm.ActiveMdiChild
Dim EventName = "Paint"
Dim EventHandlerName = "PaintBorderlessGroupBox"
If ChildForm IsNot Nothing Then
AddEventToControls(ChildForm, GetType(GroupBox), EventName, EventHandlerName)
End If
End Sub
Private Sub AddEventToControls(Control As Control, ControlType As Type, ControlEventName As String, ControlEventMethod As String)
For Each ChildControl In Control.Controls
If ChildControl.GetType = ControlType Then
If ChildControl.Controls.Count > 0 Then
AddEventToControls(ChildControl, ControlType, ControlEventName, ControlEventMethod)
End If
Dim EventMethod = Me.GetType().GetMethod(ControlEventMethod, BindingFlags.NonPublic Or BindingFlags.Instance)
Dim ControlEvent As EventInfo = ControlType.GetEvent(ControlEventName)
Dim del = [Delegate].CreateDelegate(ControlEvent.EventHandlerType, Me, EventMethod)
ControlEvent.RemoveEventHandler(ChildControl, del)
ControlEvent.AddEventHandler(ChildControl, del)
End If
Next
End Sub
调用AddEventToControls()
会将处理程序分配给该控件及其也将应用于的任何子控件。在本例中,我将控件.Paint
事件设置为以特定方式绘制组框。这可能不是实现这一点的最干净的方法,但我能够为所有子窗体创建一个“全局事件”,而不必触及每个窗体上的代码 我可以通过使用Form.mdichildactive
并基于事件和事件处理程序将事件添加到相应的控件中来完成此操作
Private Sub frmMain_MdiChildActivate(sender As Object, e As EventArgs) Handles Me.MdiChildActivate
Dim ParentForm As frmMain = sender
Dim ChildForm = ParentForm.ActiveMdiChild
Dim EventName = "Paint"
Dim EventHandlerName = "PaintBorderlessGroupBox"
If ChildForm IsNot Nothing Then
AddEventToControls(ChildForm, GetType(GroupBox), EventName, EventHandlerName)
End If
End Sub
Private Sub AddEventToControls(Control As Control, ControlType As Type, ControlEventName As String, ControlEventMethod As String)
For Each ChildControl In Control.Controls
If ChildControl.GetType = ControlType Then
If ChildControl.Controls.Count > 0 Then
AddEventToControls(ChildControl, ControlType, ControlEventName, ControlEventMethod)
End If
Dim EventMethod = Me.GetType().GetMethod(ControlEventMethod, BindingFlags.NonPublic Or BindingFlags.Instance)
Dim ControlEvent As EventInfo = ControlType.GetEvent(ControlEventName)
Dim del = [Delegate].CreateDelegate(ControlEvent.EventHandlerType, Me, EventMethod)
ControlEvent.RemoveEventHandler(ChildControl, del)
ControlEvent.AddEventHandler(ChildControl, del)
End If
Next
End Sub
调用AddEventToControls()
会将处理程序分配给该控件及其也将应用于的任何子控件。在本例中,我将控件.Paint
事件设置为以特定方式绘制组框。这可能不是实现这一点的最干净的方法,但我能够为所有子窗体创建一个“全局事件”,而不必触及每个窗体上的代码 确实有,您试图做什么?创建一个包含所有共享属性值的静态类(VB中的模块)。此外,您还可以继承表单
,并根据您的需要对其进行自定义needs@Codexer我在父窗体中创建了一个MdiChildActivate事件,该事件为我要在子窗体中更改的每个控件创建一个绘制事件处理程序。问题是这对嵌套控件不起作用。@jonathana我不想在现有窗体中添加任何代码,除了父窗体之外。@jonathana我不想在现有窗体中添加任何代码。如果不想添加任何代码,您打算如何解决此问题?我同意,为共享属性创建一个模块。确实有,您试图做什么?创建一个包含所有共享属性值的静态类(VB中的模块)。此外,您还可以继承表单
,并根据您的需要对其进行自定义needs@Codexer我在父窗体中创建了一个MdiChildActivate事件,该事件为我要在子窗体中更改的每个控件创建一个绘制事件处理程序。问题是这对嵌套控件不起作用。@jonathana我不想在现有窗体中添加任何代码,除了父窗体之外。@jonathana我不想在现有窗体中添加任何代码。如果不想添加任何代码,您打算如何解决此问题?我同意,为共享属性创建一个模块。这对子窗体是如何工作的?在代码示例中,已将ChildForm设置为控件,而不是窗体。因此,它不会回答您自己的问题(“我想为所有打开的窗体上的某种类型的控件设置背景色。我有一个父窗体,用于打开其他窗体。”)。如果您能演示如何对子窗体进行此操作,我很高兴删除否决票,非子控件。@AJD这适用于所有子窗体,因为它们包含在父窗体中。查看父窗体的活动控件时,您会发现在本例中返回子窗体,因为我们在MdiChildActivate事件处理程序中。使用Form.ActiveControl将子窗体作为控件返回。我已将其更改为Form.ActiveMdiChild,这将返回一个表单,该表单仍然用作AddEventToControls()中的控件。OP中缺少该上下文,我认为子表单是独立于父表单的派生表单。我的另一个印象是,颜色的变化发生在孩子们出生后。添加此上下文和clea