简体   繁体   English

使用名称访问和禁用 ToolStripItems(ToolStripButtons、ToolStripMenuItems)

[英]Access and disable ToolStripItems (ToolStripButtons, ToolStripMenuItems) using their names

I would like to disable UI elements (Controls, Components etc.) which names are stored in a database.我想禁用名称存储在数据库中的 UI 元素(控件、组件等)。
My code works for Controls, but I would like to access (to disable them) ToolStripItems such as ToolStripButtons, ToolStripMenuItems etc..我的代码适用于控件,但我想访问(禁用它们)ToolStripItems,例如 ToolStripButtons、ToolStripMenuItems 等。

This is my current code:这是我当前的代码:

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

You cannot find ToolStrip or MenuStrip Items in the Form.Control collection because those UI elements are not Controls but a special breed of Components.在 Form.Control 集合中找不到 ToolStrip 或 MenuStrip 项,因为这些 UI 元素不是控件,而是一种特殊的组件。
While ToolStrip and MenuStrip both inherit from Control, ToolStripMenuItems inherit from Component and ToolStripItem (the latter provides the Enabled property).虽然 ToolStrip 和 MenuStrip 都继承自 Control,但 ToolStripMenuItems 继承自 Component 和ToolStripItem (后者提供Enabled属性)。

You could build a Dictionary(Of String, Boolean) containing the names of the UI elements to enable or disable, based on values stored in the data source you have.您可以根据存储在您拥有的数据源中的值构建一个包含要启用或禁用的 UI 元素名称的Dictionary(Of String, Boolean)

The use a method that reads the current Form's Fields, loop the KeyValuePairs in the Dictionary to find elements matching the Dictionary Keys and sets the Enable property based on the corresponding Values .使用读取当前 Form 的 Fields 的方法,循环 Dictionary 中的KeyValuePairs以查找与 Dictionary Keys匹配的元素,并根据相应的Values设置Enable属性。

For example, to disabled all the elements in the collection:例如,禁用集合中的所有元素:
(I assume you have stored all different names per each Form in your data source) (我假设您在数据源中为每个表单存储了所有不同的名称)

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)

The method use Type.GetFields() to find all non public instance fields of the specified Form, the FieldInfo.GetValue() to get the instance of a UI element represented by that Field.该方法使用Type.GetFields()查找指定Form 的所有非公共实例字段, FieldInfo.GetValue()获取该字段表示的UI 元素的实例。

It then determines whether the UI element is a Control or a ToolStripItem (UI elements that inherit from these base classes have an Enabled property) and sets it using the Value stored in the Dictionary.然后,它确定 UI 元素是 Control 还是 ToolStripItem(从这些基类继承的 UI 元素具有Enabled属性)并使用存储在 Dictionary 中的 Value 对其进行设置。

TrimStart("_"c) is there because VB.Net has the (IMO) bad habit to add an underscore to these Field names. TrimStart("_"c)之所以存在,是因为 VB.Net 有(IMO)在这些字段名称中添加下划线的坏习惯。 It doesn't happen using C#.使用 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

The items collection of the 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. ToolStrip和派生控件MenuStripContextMenuStripStatusStrip的项目集合是ToolStripItemCollection ,它具有用于深度搜索的Find方法,就像ControlCollection.Find方法一样。 So you have to search this collection through the Items properties of the mentioned controls for a ToolStripItem or any derived type.因此,您必须通过上述控件的Items属性搜索此集合,以查找ToolStripItem或任何派生类型。

Create a search function for the mentioned classes:为上述类创建搜索 function:

Public Function GetToolStripItem(toolStrip As ToolStrip, key As String) As ToolStripItem
    Return toolStrip.Items.Find(key, True).FirstOrDefault
End Function

... and call it as follows: ...并按如下方式调用它:

'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

Also, you can use the TypeOf operator to determine the type of an item:此外,您可以使用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

... and use the iterator functions to get all or a specific type of items from the collections: ...并使用迭代器函数从 collections 中获取所有或特定类型的项目:

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

... and the usage: ...以及用法:

'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)

Note that in the iterators, identifying the ToolStripDropDownItem is necessary to get the ToolStripItemCollection of derived classes including:请注意,在迭代器中,识别ToolStripDropDownItem是获取派生类的ToolStripItemCollection所必需的,包括:

Each of which inherits the DropDownItems property which of course should be passed to the iterator.每个都继承DropDownItems属性,当然应该将其传递给迭代器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ToolStripMenuSeparator防止以编程方式禁用/启用ToolStripMenuItems - ToolStripMenuSeparator prevents Disable/Enable programmatically of ToolStripMenuItems 如何使用递归提取 ContextMenuStrip 的所有 ToolStripMenuItems? - How to extract all ToolStripMenuItems of a ContextMenuStrip using recursion? ToolStripItems没有显示出来 - ToolStripItems not Showing Up 您可以使用其名称作为字符串而不是对象来访问对象吗? - Can you access objects by using their names as a string, instead of a object? VB .NET验证许多ToolstripMenuItems的检查状态 - VB .NET Verify checked status of many ToolstripMenuItems 如何在VB.NET中使用SQL从特定数据库中检索Ms访问表名称 - How to retrieve Ms access tables names from specific database using SQL in VB.NET 使用VB.NET从Access数据库中的表中获取列名 - get column names from a table in an Access database using VB.NET JSON(newtonsoft)在VB.net中使用MS Access字段名称反序列化 - JSON (newtonsoft) deserialize using MS Access field names, in VB.net 如何在没有鼠标事件的情况下使用ToolStripMenuItems(单击或双击事件)? - How to use ToolStripMenuItems without mouse events ( click or double Click event )? Access数据库 - 检索存储查询的名称? - Access database - Retrieve names of stored queries?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM