在 C# 或 Vb.Net 中,使用托管或非托管代码,如何检索 NotifyIcon
的所有者 Form
?
我已经检查了 NotifyIcon
类的基本类型以及 ComponentConverter
试图找出可能的类型转换来获取表单,但我无法到。
我还看到了 NotifyIcon.ContextMenuStrip.FindForm()
函数,但出于任何原因,当我分配一个上下文菜单时,FindForm()
函数总是返回空引用异常(exception),无论如何,即使它可以工作也不是一个安全的方法,因为我可以有一个没有上下文菜单的通知图标。
我的目的是将一个 NotifyIcon
作为参数传递给一些将执行常见任务的方法,以节省我的时间并减少代码。
伪例子:
Public Shared Sub MinimizeToSystray(ByVal ntfy As NotifyIcon)
If (ntfy Is Nothing) Then
Throw New ArgumentNullException(paramName:="ntfy")
ElseIf (ntfy.Icon Is Nothing) Then
Throw New ArgumentException(message:="The NotifyIcon doesn't have an icon.",
paramName:="ntfy")
Else
Dim f As Form = ntfy.GetOwnerForm()
f.WindowState = FormWindowState.Minimized
f.Hide()
ntfy.Visible = True
End If
End Sub
最佳答案
FindForm() 方法只能找到控件的窗体。派生自 Control 并通过其 Parent 属性嵌入到窗体中的类型。但是 NotifyIcon 不是控件,它是 Component。一个组件只有一个站点属性,它的值只在设计时定义。
组件和表单之间存在一种随意的关系,Winforms promise 会自动处理任何具有采用 IContainer 参数的构造函数重载的组件。并非所有人都这样做,例如 OpenFormDialog 和 BackgroundWorker 不这样做,NotifyIcon 这样做。当不需要处理时,它们会省略构造函数。
这使得技术上可以找回表单。您需要迭代 Application.OpenForms()。并使用反射来迭代他们私有(private)的 components
集合。请注意,这仅在实际打开表单时有效,必须调用其 Show() 方法。
这是一个得分为 -100 分的解决方案,它既丑陋又容易出错。简单且始终正确的解决方案是向方法添加一个额外的参数以允许传递“所有者”表单。假设调用者需要知道 NotifyIcon 实例,它也应该知道表单。通常是我
。
关于c# - 获取 NotifyIcon 的所有者表单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33939858/