gpt4 book ai didi

vb.net - 将事件添加到项目中的所有表单

转载 作者:行者123 更新时间:2023-12-05 00:12:13 24 4
gpt4 key购买 nike

如果我想显示每个 Form 的大小在我的项目中 Form 's Title 最好的方法是什么?
我不想在每个 Form 中手动放置一个事件处理程序.
我希望这个过程是自动的。类似于重载的 Load()在 resize 事件上添加处理程序的事件。

最佳答案

这是实现 Automation 的尝试问题的解决方案。
问题:
将一个或多个事件处理程序附加到项目中的每个现有表单(或它们的子集),而无需编辑/修改这些类现有代码。
UIAutomation 提供了一个可能的解决方案,它提供了检测新窗口何时打开并将事件报告给它自己的订阅者的方法Automation.AddAutomationEventHandler , 当 EventIdAutomationEvent设置为 WindowPattern图案。
AutomationElement成员必须设置为 AutomationElement.RootElementScope成员(member) TreeScope.SubTree .Automation , 对于每个 AutomationElement这引发了AutomationEvent ,报告:

  • Element.Name (对应Windows Title)
  • Process ID
  • Window Handle (作为整数值)

  • 这些值足以识别属于当前进程的 Window;窗口句柄允许识别打开的 Form例如,测试 Application.OpenForms()收藏。
    当表格被单选出来时,一个新的 Event Handler可以附加到 Event选择。
    通过扩展这个概念,可以创建一个预定义的事件列表和一个表单列表来附加这些事件。
    可能,需要时将类文件包含在项目中。
    请注意,某些事件在这种情况下没有意义,因为 Automation当窗口已经显示时报告它的打开,因此 Load()Shown()事件属于过去。

    我已经用几个事件( Form.Resize()Form.Activate() )对此进行了测试,但在这里的代码中我只使用了 .Resize()为简单起见。
    这是该过程的图形表示。
    启动应用程序,事件处理程序未附加到 .Resize()事件。
    只是因为一个 Boolean字段设置为 False .
    单击按钮, Boolean字段设置为 True ,启用事件处理程序的注册。
    .Resize()事件注册后,所有Forms的Title都会报告Window的当前大小。
    Global Handlers
    测试环境 : Visual Studio 2017 pro 15.7.5 .Net FrameWork 4.7.1 导入的命名空间: System.Windows.Automation 引用组件 : UIAutomationClient UIAutomationTypes MainForm代码:
    Imports System.Diagnostics
    Imports System.Windows
    Imports System.Windows.Automation

    Public Class MainForm

    Friend GlobalHandlerEnabled As Boolean = False
    Protected Friend FormsHandler As List(Of Form) = New List(Of Form)
    Protected Friend ResizeHandler As EventHandler

    Public Sub New()

    InitializeComponent()

    ResizeHandler =
    Sub(obj, args)
    Dim CurrentForm As Form = TryCast(obj, Form)
    CurrentForm.Text = CurrentForm.Text.Split({" ("}, StringSplitOptions.None)(0) &
    $" ({CurrentForm.Width}, {CurrentForm.Height})"
    End Sub

    Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,
    AutomationElement.RootElement,
    TreeScope.Subtree,
    Sub(UIElm, evt)
    If Not GlobalHandlerEnabled Then Return
    Dim element As AutomationElement = TryCast(UIElm, AutomationElement)
    If element Is Nothing Then Return

    Dim NativeHandle As IntPtr = CType(element.Current.NativeWindowHandle, IntPtr)
    Dim ProcessId As Integer = element.Current.ProcessId
    If ProcessId = Process.GetCurrentProcess().Id Then
    Dim CurrentForm As Form = Nothing
    Invoke(New MethodInvoker(
    Sub()
    CurrentForm = Application.OpenForms.
    OfType(Of Form)().
    FirstOrDefault(Function(f) f.Handle = NativeHandle)
    End Sub))

    If CurrentForm IsNot Nothing Then
    Dim FormName As String = FormsHandler.FirstOrDefault(Function(f) f?.Name = CurrentForm.Name)?.Name
    If Not String.IsNullOrEmpty(FormName) Then
    RemoveHandler CurrentForm.Resize, ResizeHandler
    FormsHandler.Remove(FormsHandler.Where(Function(fn) fn.Name = FormName).First())
    End If
    Invoke(New MethodInvoker(
    Sub()
    CurrentForm.Text = CurrentForm.Text & $" ({CurrentForm.Width}, {CurrentForm.Height})"
    End Sub))

    AddHandler CurrentForm.Resize, ResizeHandler
    FormsHandler.Add(CurrentForm)
    End If
    End If
    End Sub)
    End Sub


    Private Sub btnOpenForm_Click(sender As Object, e As EventArgs) Handles btnOpenForm.Click
    Form2.Show(Me)
    End Sub

    Private Sub btnEnableHandlers_Click(sender As Object, e As EventArgs) Handles btnEnableHandlers.Click
    GlobalHandlerEnabled = True
    Me.Hide()
    Me.Show()
    End Sub

    Private Sub btnDisableHandlers_Click(sender As Object, e As EventArgs) Handles btnDisableHandlers.Click
    GlobalHandlerEnabled = False
    If FormsHandler IsNot Nothing Then
    For Each Item As Form In FormsHandler
    RemoveHandler Item.Resize, ResizeHandler
    Item = Nothing
    Next
    End If
    FormsHandler = New List(Of Form)
    Me.Text = Me.Text.Split({" ("}, StringSplitOptions.RemoveEmptyEntries)(0)
    End Sub
    End Class
    注:
    之前的代码放置在应用程序的启动表单中(用于测试),但最好在需要时将模块包含在项目中,而无需触及当前代码。
    要使其正常工作,请添加一个新模块(名为 Program ),其中包含 Public Sub Main() ,并更改项目属性以从 Sub Main() 启动应用程序而不是表格。
    删除 Use Application Framework 上的复选标记并选择 Sub Main来自 Startup object组合。
    所有代码都可以转移到 Sub Main proc 进行了一些修改:
    Imports System
    Imports System.Diagnostics
    Imports System.Windows
    Imports System.Windows.Forms
    Imports System.Windows.Automation

    Module Program

    Friend GlobalHandlerEnabled As Boolean = True
    Friend FormsHandler As List(Of Form) = New List(Of Form)
    Friend ResizeHandler As EventHandler

    Public Sub Main()

    Application.EnableVisualStyles()
    Application.SetCompatibleTextRenderingDefault(False)

    Dim MyMainForm As MainForm = New MainForm()

    ResizeHandler =
    Sub(obj, args)
    Dim CurrentForm As Form = TryCast(obj, Form)
    CurrentForm.Text = CurrentForm.Text.Split({" ("}, StringSplitOptions.None)(0) &
    $" ({CurrentForm.Width}, {CurrentForm.Height})"
    End Sub

    Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,
    AutomationElement.RootElement,
    TreeScope.Subtree,
    Sub(UIElm, evt)
    If Not GlobalHandlerEnabled Then Return
    Dim element As AutomationElement = TryCast(UIElm, AutomationElement)
    If element Is Nothing Then Return

    Dim NativeHandle As IntPtr = CType(element.Current.NativeWindowHandle, IntPtr)
    Dim ProcessId As Integer = element.Current.ProcessId
    If ProcessId = Process.GetCurrentProcess().Id Then
    Dim CurrentForm As Form = Nothing
    If Not MyMainForm.IsHandleCreated Then Return
    MyMainForm.Invoke(New MethodInvoker(
    Sub()
    CurrentForm = Application.OpenForms.
    OfType(Of Form)().
    FirstOrDefault(Function(f) f.Handle = NativeHandle)
    End Sub))
    If CurrentForm IsNot Nothing Then
    Dim FormName As String = FormsHandler.FirstOrDefault(Function(f) f?.Name = CurrentForm.Name)?.Name
    If Not String.IsNullOrEmpty(FormName) Then
    RemoveHandler CurrentForm.Resize, ResizeHandler
    FormsHandler.Remove(FormsHandler.Where(Function(fn) fn.Name = FormName).First())
    End If

    AddHandler CurrentForm.Resize, ResizeHandler
    FormsHandler.Add(CurrentForm)

    CurrentForm.Invoke(New MethodInvoker(
    Sub()
    CurrentForm.Text = CurrentForm.Text & $" ({CurrentForm.Width}, {CurrentForm.Height})"
    End Sub))
    End If
    End If
    End Sub)

    Application.Run(MyMainForm)

    End Sub

    End Module

    关于vb.net - 将事件添加到项目中的所有表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51491566/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com