Доступ и отключение ToolStripItems (ToolStripButtons, ToolStripMenuItems), используя их имена - PullRequest
2 голосов
/ 29 мая 2020

Я хотел бы отключить элементы пользовательского интерфейса (элементы управления, компоненты и т. Д. c.), Имена которых хранятся в базе данных.
Мой код работает для элементов управления, но я хотел бы получить доступ (чтобы отключить их) ToolStripItems, например как ToolStripButtons, ToolStripMenuItems и т. д. c ..

Это мой текущий код:

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

Ответы [ 2 ]

1 голос
/ 29 мая 2020

Коллекция элементов ToolStrip и производных элементов управления, MenuStrip , ContextMenuStrip , StatusStrip - это ToolStripItemCollection , который имеет метод Find для глубокого поиска, как и метод ControlCollection.Find . Таким образом, вам необходимо выполнить поиск в этой коллекции через свойства Items упомянутых элементов управления для 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

... и используйте функции итератора , чтобы получить все или определенный c тип элементов из коллекций:

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 необходима для получения ToolStripItemCollection производных классов, включая:

Каждый из которых наследуется свойство DropDownItems , которое, конечно же, должно быть передано итератору .

1 голос
/ 29 мая 2020

Вы не можете найти элементы ToolStrip или MenuStrip в коллекции Form.Control, потому что эти элементы пользовательского интерфейса не являются элементами управления, а представляют собой особую породу компонентов.
Хотя ToolStrip и MenuStrip наследуются от Control, ToolStripMenuItems наследуются от Component и ToolStripItem (последний предоставляет свойство Enabled).

Вы можете создать Dictionary(Of String, Boolean), содержащий имена элементов пользовательского интерфейса, которые нужно включить или отключить, на основе значений, хранящихся в имеющемся у вас источнике данных.

Используйте метод, который считывает поля текущей формы, l oop the 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 () , чтобы найти все не опубликованные c поля экземпляра указанной формы, FieldInfo.GetValue () для получения экземпляра Элемент пользовательского интерфейса, представленный этим полем.

Затем он определяет, является ли элемент пользовательского интерфейса Control или ToolStripItem (элементы пользовательского интерфейса, которые наследуются от этих базовых классов, имеют свойство 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
...