I would like to disable UI elements (Controls, Components etc.) which names are stored in a database.
My code works for Controls, but I would like to access (to disable them) ToolStripItems such as ToolStripButtons, ToolStripMenuItems etc..
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.
While ToolStrip and MenuStrip both inherit from Control, ToolStripMenuItems inherit from Component and ToolStripItem (the latter provides the Enabled
property).
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.
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
.
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.
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.
TrimStart("_"c)
is there because VB.Net has the (IMO) bad habit to add an underscore to these Field names. It doesn't happen using 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