使用名称访问和禁用 ToolStripItems(ToolStripButtons、ToolStripMenuItems)
Access and disable ToolStripItems (ToolStripButtons, ToolStripMenuItems) using their names
我想禁用名称存储在数据库中的 UI 个元素(控件、组件等)。
我的代码适用于控件,但我想访问(禁用它们)ToolStripItems,例如 ToolStripButtons、ToolStripMenuItems 等。
这是我当前的代码:
Dim df_command As New SqlCommand("select * from treftab where ref_data = 'INTERVENTION' and ref_code = '0'", sfacon)
Dim df_reader As SqlDataReader = df_command.ExecuteReader
If df_reader.HasRows Then
While df_reader.Read
Dim reftext As String = df_reader("ref_text")
Dim someVariable As Control = Nothing
Dim SearchedControls = Me.Controls.Find(key:=reftext, searchAllChildren:=True)
someVariable = SearchedControls(0)
someVariable.Enabled = False
End While
End If
您在 Form.Control 集合中找不到 ToolStrip 或 MenuStrip 项,因为这些 UI 元素不是控件,而是一种特殊的组件。
ToolStrip 和 MenuStrip 都继承自 Control,ToolStripMenuItems 继承自 Component 和 ToolStripItem(后者提供了 Enabled
属性)。
您可以构建一个 Dictionary(Of String, Boolean)
,其中包含要启用或禁用的 UI 元素的名称,具体取决于存储在您拥有的数据源中的值。
使用读取当前表单字段的方法,在字典中循环KeyValuePairs
以查找与字典Keys
匹配的元素并设置Enable
属性基于相应的Values
。
例如,要禁用集合中的所有元素:
(我假设您已经在数据源中为每个表单存储了所有不同的名称)
Dim names As New Dictionary(Of String, Boolean)()
' [...]
While df_reader.Read()
names.Add(df_reader("ref_text").ToString(), False)
End While
EnableDisableFormElements(Me, names)
该方法使用 Type.GetFields() to find all non public instance fields of the specified Form, the FieldInfo.GetValue() 获取由该字段表示的 UI 元素的实例。
然后确定 UI 元素是 Control 还是 ToolStripItem(从这些基础 类 继承的 UI 元素具有 Enabled
属性) 并使用存储在字典中的值设置它。
TrimStart("_"c)
之所以存在,是因为 VB.Net 有(IMO)在这些字段名称中添加下划线的坏习惯。使用 C# 不会发生这种情况。
Imports System.Reflection
Imports System.Windows.Forms
Private Sub EnableDisableFormElements(parentForm As Form, elementNames As Dictionary(Of String, Boolean))
Dim allFields = parentForm.GetType().GetFields(BindingFlags.NonPublic Or BindingFlags.Instance)
For Each element As KeyValuePair(Of String, Boolean) In elementNames
Dim searchElement = allFields.FirstOrDefault(
Function(f) f.Name.TrimStart("_"c).Equals(element.Key)).GetValue(parentForm)
If searchElement IsNot Nothing Then
If TypeOf searchElement Is Control Then
DirectCast(searchElement, Control).Enabled = element.Value
ElseIf TypeOf searchElement Is ToolStripItem Then
DirectCast(searchElement, ToolStripItem).Enabled = element.Value
End If
End If
Next
End Sub
ToolStrip and the derived controls, MenuStrip, ContextMenuStrip, StatusStrip is the ToolStripItemCollection which has a Find method for the deep search just like the ControlCollection.Find method. So you have to search this collection through the Items properties of the mentioned controls for a ToolStripItem 或任何派生类型的项集合。
为提到的类创建一个搜索功能:
Public Function GetToolStripItem(toolStrip As ToolStrip, key As String) As ToolStripItem
Return toolStrip.Items.Find(key, True).FirstOrDefault
End Function
... 并按如下方式调用它:
'Search a MenuStrip
Dim tsi = GetToolStripItem(MenuStrip1, key)
'Search a ToolStrip
Dim tsi = GetToolStripItem(ToolStrip1, key)
'Search a ContextMenuStrip
Dim tsi = GetToolStripItem(ContextMenuStrip1, key)
'Search a StatusStrip
Dim tsi = GetToolStripItem(StatusStrip1, key)
If tsi IsNot Nothing Then
tsi.Enabled = False
End If
此外,您可以使用 TypeOf 运算符来确定项目的类型:
If TypeOf tsi Is ToolStripMenuItem Then
'...
End If
If TypeOf tsi Is ToolStripDropDownItem Then
'...
End If
If TypeOf tsi Is ToolStripButton Then
'...
End If
...并使用迭代器函数从集合中获取所有或特定类型的项目:
Public Iterator Function GetAllToolStripItems(items As ToolStripItemCollection) As _
IEnumerable(Of ToolStripItem)
For Each tsi As ToolStripItem In items
Yield tsi
If TypeOf tsi Is ToolStripDropDownItem Then
For Each ddi As ToolStripItem In
GetAllToolStripItems(DirectCast(tsi, ToolStripDropDownItem).DropDownItems)
Yield ddi
Next
End If
Next
End Function
Public Iterator Function GetAllToolStripItems(Of T)(items As ToolStripItemCollection) As _
IEnumerable(Of T)
For Each tsi In items
If TypeOf tsi Is T Then
Yield DirectCast(tsi, T)
ElseIf TypeOf tsi Is ToolStripDropDownItem Then
For Each ddi In
GetAllToolStripItems(Of T)(DirectCast(tsi, ToolStripDropDownItem).DropDownItems)
Yield ddi
Next
End If
Next
End Function
...和用法:
'Get them all...
Dim items = GetAllToolStripItems(TooStrip1.Items) 'or any derived control...
'Get for example the ToolStripComboBox items...
Dim items = GetAllToolStripItems(Of ToolStripComboBox)(MenuStrip1.Items)
请注意,在迭代器中,识别派生 类 的 ToolStripDropDownItem is necessary to get the ToolStripItemCollection 包括:
每个都继承 DropDownItems 属性 当然应该传递给迭代器。
我想禁用名称存储在数据库中的 UI 个元素(控件、组件等)。
我的代码适用于控件,但我想访问(禁用它们)ToolStripItems,例如 ToolStripButtons、ToolStripMenuItems 等。
这是我当前的代码:
Dim df_command As New SqlCommand("select * from treftab where ref_data = 'INTERVENTION' and ref_code = '0'", sfacon)
Dim df_reader As SqlDataReader = df_command.ExecuteReader
If df_reader.HasRows Then
While df_reader.Read
Dim reftext As String = df_reader("ref_text")
Dim someVariable As Control = Nothing
Dim SearchedControls = Me.Controls.Find(key:=reftext, searchAllChildren:=True)
someVariable = SearchedControls(0)
someVariable.Enabled = False
End While
End If
您在 Form.Control 集合中找不到 ToolStrip 或 MenuStrip 项,因为这些 UI 元素不是控件,而是一种特殊的组件。
ToolStrip 和 MenuStrip 都继承自 Control,ToolStripMenuItems 继承自 Component 和 ToolStripItem(后者提供了 Enabled
属性)。
您可以构建一个 Dictionary(Of String, Boolean)
,其中包含要启用或禁用的 UI 元素的名称,具体取决于存储在您拥有的数据源中的值。
使用读取当前表单字段的方法,在字典中循环KeyValuePairs
以查找与字典Keys
匹配的元素并设置Enable
属性基于相应的Values
。
例如,要禁用集合中的所有元素:
(我假设您已经在数据源中为每个表单存储了所有不同的名称)
Dim names As New Dictionary(Of String, Boolean)()
' [...]
While df_reader.Read()
names.Add(df_reader("ref_text").ToString(), False)
End While
EnableDisableFormElements(Me, names)
该方法使用 Type.GetFields() to find all non public instance fields of the specified Form, the FieldInfo.GetValue() 获取由该字段表示的 UI 元素的实例。
然后确定 UI 元素是 Control 还是 ToolStripItem(从这些基础 类 继承的 UI 元素具有 Enabled
属性) 并使用存储在字典中的值设置它。
TrimStart("_"c)
之所以存在,是因为 VB.Net 有(IMO)在这些字段名称中添加下划线的坏习惯。使用 C# 不会发生这种情况。
Imports System.Reflection
Imports System.Windows.Forms
Private Sub EnableDisableFormElements(parentForm As Form, elementNames As Dictionary(Of String, Boolean))
Dim allFields = parentForm.GetType().GetFields(BindingFlags.NonPublic Or BindingFlags.Instance)
For Each element As KeyValuePair(Of String, Boolean) In elementNames
Dim searchElement = allFields.FirstOrDefault(
Function(f) f.Name.TrimStart("_"c).Equals(element.Key)).GetValue(parentForm)
If searchElement IsNot Nothing Then
If TypeOf searchElement Is Control Then
DirectCast(searchElement, Control).Enabled = element.Value
ElseIf TypeOf searchElement Is ToolStripItem Then
DirectCast(searchElement, ToolStripItem).Enabled = element.Value
End If
End If
Next
End Sub
ToolStrip and the derived controls, MenuStrip, ContextMenuStrip, StatusStrip is the ToolStripItemCollection which has a Find method for the deep search just like the ControlCollection.Find method. So you have to search this collection through the Items properties of the mentioned controls for a ToolStripItem 或任何派生类型的项集合。
为提到的类创建一个搜索功能:
Public Function GetToolStripItem(toolStrip As ToolStrip, key As String) As ToolStripItem
Return toolStrip.Items.Find(key, True).FirstOrDefault
End Function
... 并按如下方式调用它:
'Search a MenuStrip
Dim tsi = GetToolStripItem(MenuStrip1, key)
'Search a ToolStrip
Dim tsi = GetToolStripItem(ToolStrip1, key)
'Search a ContextMenuStrip
Dim tsi = GetToolStripItem(ContextMenuStrip1, key)
'Search a StatusStrip
Dim tsi = GetToolStripItem(StatusStrip1, key)
If tsi IsNot Nothing Then
tsi.Enabled = False
End If
此外,您可以使用 TypeOf 运算符来确定项目的类型:
If TypeOf tsi Is ToolStripMenuItem Then
'...
End If
If TypeOf tsi Is ToolStripDropDownItem Then
'...
End If
If TypeOf tsi Is ToolStripButton Then
'...
End If
...并使用迭代器函数从集合中获取所有或特定类型的项目:
Public Iterator Function GetAllToolStripItems(items As ToolStripItemCollection) As _
IEnumerable(Of ToolStripItem)
For Each tsi As ToolStripItem In items
Yield tsi
If TypeOf tsi Is ToolStripDropDownItem Then
For Each ddi As ToolStripItem In
GetAllToolStripItems(DirectCast(tsi, ToolStripDropDownItem).DropDownItems)
Yield ddi
Next
End If
Next
End Function
Public Iterator Function GetAllToolStripItems(Of T)(items As ToolStripItemCollection) As _
IEnumerable(Of T)
For Each tsi In items
If TypeOf tsi Is T Then
Yield DirectCast(tsi, T)
ElseIf TypeOf tsi Is ToolStripDropDownItem Then
For Each ddi In
GetAllToolStripItems(Of T)(DirectCast(tsi, ToolStripDropDownItem).DropDownItems)
Yield ddi
Next
End If
Next
End Function
...和用法:
'Get them all...
Dim items = GetAllToolStripItems(TooStrip1.Items) 'or any derived control...
'Get for example the ToolStripComboBox items...
Dim items = GetAllToolStripItems(Of ToolStripComboBox)(MenuStrip1.Items)
请注意,在迭代器中,识别派生 类 的 ToolStripDropDownItem is necessary to get the ToolStripItemCollection 包括:
每个都继承 DropDownItems 属性 当然应该传递给迭代器。