Why i cannot find context menu strip in my form? - vb.net

I'am trying to find my context menu strip in my form but my code doesnt seem to displayed my desired output...here is my code:
Dim omnuStrip() As Object = oCollection.controls.find("mnuStrip", True)
Dim mnuStrip_ as ContextMenuStrip = DirectCast(omnuStrip,ContextMenuStrip)
mnuStrip_.Tag = "My Control"
it always return a empty array of objects...Am I doing wrong here? Please help..Thanks!

ContextMenuStrips are added to components, not controls, that's why you get an empty array.
Dim strip As ContextMenuStrip = Nothing
For Each component As Object In components.Components
strip = TryCast(component, ContextMenuStrip)
If strip IsNot Nothing Then Exit For
Next

Related

Unable to get the Event associated with a menu element to create another menu element

Hello everyone and thanks in advance for taking the time to read my question.
My scenario is as it follows: I have a fully developed software with a ToolStripMenu populated with all the DropDown menus with more elements inside.
I want to add a new feature, where I can create a new ToolStrip under the main menu with some of the "favourites" elements, something like a booksmark bar from some internet browser.
The list of favourite elements is stored in our DataBase, so I've managed to loop through every element in the main menu and its DropDownItems and locate which specific Meny Item corresponds to the favourite.
In this situation, I tried to get the EventHandlers associated with this Item, so I could pass it in the instance of the new Item that will go in the new ToolStripMenu. I've done this using an EventHandlerList.
However, eventhough this list is filled with te EventHandler for the MenuItem, I can't acces it so I could use it in the instance of the new ToolStripButton so it will fire the same method as it "twin" on the main menu. Apparently I need to use an Object named "Key", but I haven't been able to know how to get it.
I will leave the piece of code that I've come to so far: the object M_DtFavs is a DataTable with all the favourite items and "NomOpc" is the Name of the item in the main menu.
For Each L_Dr As DataRow In M_DtFavs.Rows
For Each L_Menu As ToolStripMenuItem In M_MainMenu.Items
L_Items = L_Menu.DropDownItems.Find(L_Dr("NomOpc"), True)
If L_Items.Length > 0 Then
L_EventList = getEventHandlers(L_Items(0))
Exit For
End If
Next
'L_Key -> I need this to acces the event, but I don't know what to use
If L_Items.Length > 0 Then
L_Cmd = New ToolStripButton(L_Dr("NomOpc"), My.Resources.Nuevo, L_EventList(L_key), L_Dr("NomOpc"))
L_Cmd.DisplayStyle = ToolStripItemDisplayStyle.Text
L_Cmd.ImageTransparentColor = System.Drawing.Color.Magenta
L_Cmd.Size = New System.Drawing.Size(23, 23)
L_Cmd.ToolTipText = L_Dr("NomOpc")
L_Cmd.Text = L_Items(0).Text
M_ToolBarResaltados.Items.Add(L_Cmd)
End If
Next
And here is the Function I use to get the list of handlers associated with the menu item:
Function getEventHandlers(cmpnt As System.ComponentModel.Component) As System.ComponentModel.EventHandlerList
Dim strMethodName = New System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name '...this procedure's name
Dim propInfo As System.Reflection.PropertyInfo
Dim value As System.ComponentModel.EventHandlerList = Nothing
Try
propInfo = GetType(System.ComponentModel.Component).GetProperty("Events",
Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Public Or
Reflection.BindingFlags.Static Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.DeclaredOnly)
If propInfo IsNot Nothing Then
value = CType(propInfo.GetValue(cmpnt, Nothing), System.ComponentModel.EventHandlerList)
End If
Catch ex As Exception
Finally
propInfo = Nothing
End Try
Return value
End Function
¡Thanks again!

Change Font Style on All Instances of a String in a RichTextBox

I'm working on a VB.NET 4.5 project in VS2013.
I have a richtextbox on a form and when a button is clicked I need to toggle the BOLD setting on all instances of a specific string found in the richtextbox.
I put together some code based on this question.
Private Sub ToggleBold()
rtxtOutputText.SelectionStart = rtxtOutputText.Find("##$%", RichTextBoxFinds.None)
rtxtOutputText.SelectionFont = New Font(rtxtOutputText.Font, FontStyle.Bold)
End Sub
However when the toggle bold button is clicked it only bolds the first instance of the string "##$%".
How can I set all instances of the string to bold? There can also be several of them strung together ("##$%##$%##$%"), so each of those would need to be bolded too.
(I know I mentioned toggling bold, but I'll set up the toggle portion later, right now I'm just trying to get the bold on all instances working right...)
Just add a loop to it and use the RichTextBox.Find(String, Int32, RichTextBoxFinds) overload to specify from where to start looking. Look from the current index + 1 so that it doesn't return the same again.
You also ought to actually select the word as well, so that you're sure the bold applies to the current instance only and not the text around it.
Private Sub ToggleBold()
'Stop the control from redrawing itself while we process it.
rtxtOutputText.SuspendLayout()
Dim LookFor As String = "##$%"
Dim PreviousPosition As Integer = rtxtOutputText.SelectionStart
Dim PreviousSelection As Integer = rtxtOutputText.SelectionLength
Dim SelectionIndex As Integer = -1
Using BoldFont As New Font(rtxtOutputText.Font, FontStyle.Bold)
While True
SelectionIndex = rtxtOutputText.Find(LookFor, SelectionIndex + 1, RichTextBoxFinds.None)
If SelectionIndex < 0 Then Exit While 'No more matches found.
rtxtOutputText.SelectionStart = SelectionIndex
rtxtOutputText.SelectionLength = LookFor.Length
rtxtOutputText.SelectionFont = BoldFont
End While
End Using
'Allow the control to redraw itself again.
rtxtOutputText.ResumeLayout()
'Restore the previous selection.
rtxtOutputText.SelectionStart = PreviousPosition
rtxtOutputText.SelectionLength = PreviousSelection
End Sub
Credit to Plutonix for telling me to dispose the font.

Convert Control Using Cast Not Working

i have a control named SuperValidator1 on every form with SuperValidator type. i want to find this control and enable it using its name because the name is consistent in all forms. so this is the code i came up with :
Dim validator As SuperValidator
Dim frm As Form = Me.ParentForm
Dim ctrl As Control()
ctrl = frm.Controls.Find("SuperValidator1", True)
Dim singleCtrl As Control = ctrl(0)
validator = TryCast(singleCtrl, SuperValidator) '< ERROR LINE
it throws editor error : Value of Type 'Control' cannot be converted to 'SuperValidator'
i tried CType and DirectCast but it is the same. according to this i should be able to cast any data type. what is wrong and what should i do ?
btw SuperValidator is from DevComponents.DotNetBar.Validator
thanks
Since SuperValidator is a component you must get it from your form's component collection. However at runtime components don't seem to inherit a name, so finding the exact one might be tricky.
As far as I know your only options are:
A) Get the first SuperValidator you can find, or
B) Match its properties (if possible).
Either way you do it you must iterate through the Me.components.Components collection:
Dim validator As SuperValidator = Nothing
For Each component In Me.components.Components
If component.GetType() Is GetType(SuperValidator) Then
validator = DirectCast(component, SuperValidator)
'Perform additional property checking here if you go with Option B.
End If
Next
Here is a test that uses a control I have on a form. Changed your logic slightly. Give it s try and see what results you have.
Dim validator As RichTextBox ' SuperValidator
Dim frm As Form = Me ' .ParentForm
Dim ctrl() As Control = frm.Controls.Find("RichTextBox1", True) ' ("SuperValidator1", True)
If ctrl.Length > 0 Then
validator = TryCast(ctrl(0), RichTextBox) ' , SuperValidator) < ERROR LINE
Else
Stop
End If

How to reference controls located on different Tabs (VB.NET)

I have an application written in VB.NET that reads data from a file and displays the data on the screen.
Depending on the data in the file, the program has a TabControl with up to 3 tabs and each tab in turn has a DataGridView for displaying data. For example I have a TabControl that has a tab called "Saturday" and a tab called "Sunday".
The problem I am having is that when I read data from a file, the program displays all the data on the Saturday's tab grid because I am not sure how to reference the Grid on the Sunday tab.
To add the DataGridView I am using the following code:
Grid = New DataGridView
Grid.Dock = DockStyle.Fill
Grid.Name = "Grid" & TabControl.SelectedIndex
Grid.Tag = "Grid" & TabControl.SelectedIndex
And this is how I am reading the data in:
If reader.GetAttribute("controltype") = "Tab" Then
SelectedTab = reader.Name
End If
If reader.Name = "cell" Then
y = y + 1
Grid.Rows(i).Cells(y).Style.BackColor = Color.FromName(reader.ReadElementString("cell"))
End If
What I almost want to do is something like (pseudocode):
SelectedTab.Grid.Rows(i).Cells(y).Style.BackColor = Color.FromName(reader.ReadElementString("cell"))
However when I use the above code it complains:
'Grid' is not a member of 'String'
I hope you understand the issue. Let me know if you need clarification
Your code is a little unclear. However, it appears to me that the following line:
If reader.GetAttribute("controltype") = "Tab" Then
SelectedTab = reader.Name
End If
is creating at least one problem. It looks like you are attempting to refer to a Tabpage control by the string representation of its name, but unless I missed something, what that line is actually doing is trying to make a tabpage control type("SelectedTab") refer to a string type. If that is the case, then you will want to try this instead:
If reader.GetAttribute("controltype") = "Tab" Then
TabControl1.SelectedTab = TabControl1.TabPages(reader.name)
End If
It is a little hard to tell from the code you have posted, but that might get you headed down the right path.
++++++++++++
UPDATE: It appears from your code that you are naming each DGV control by appending the index of the tab on which it is located to the string "grid." I am going to assume that you are using a class member variable named "SelectedTab" to represent the current tab selected in the control. I will assume that at the top of your class you have done something like this:
'Form-or-class scoped memebr variables:
Private SelectedTab As TabPage
Private SelectedGrid As DataGridView
You should be able to refer to the active grid control using something like this:
Private Sub TabControl1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
' Set SelectedTab member variable to refer to the new selected tab page:
SelectedTab = TabControl1.SelectedTab
' Set the SelectedGrid to refer to the grid control hosted on the selected tab page:
SelectedGrid = TabControl1.SelectedTab.Controls("Grid" & TabControl1.SelectedIndex.ToString())
End Sub
From here, you should be able to use the member variable for SelectedGrid to refer to the grid present on which ever tab page is selected in your tab control.
It is challenging to address your concerns with only fragments of your code. If you have additional difficulties, please post more of your code, so we can better see what else is going on.
Hope that helps!
Okay, I would go about something like this. Maybe you can simply use a DataSet to load the XML data in one line (if they have been saved with DataSet.WriteXML before).
Dim ds As New DataSet
Dim p As TabPage
Dim gv As DataGridView
ds.ReadXml("F:\testdata.xml")
For i As Integer = TabControl1.TabPages.Count - 1 To 0 Step -1
TabControl1.TabPages.RemoveAt(i)
Next
For Each dt As DataTable In ds.Tables
p = New TabPage(dt.TableName)
gv = New DataGridView
' ... configure the gv here...
gv.AutoGenerateColumns = True
gv.Dock = DockStyle.Fill
' ...
gv.DataSource = dt
TabControl1.TabPages.Add(p)
p.Controls.Add(gv)
Next

VB.NET - Adding items to a listview as well as checkboxes and tag property

I've got this code which basically loops through a set of folders and subfolders and finds specific file types. And then lists these in a listview. Now, it's intended to list exe and msi files. And I've made it so that these icons can be doubleclicked after they have been listed. I do this by adding the path to the file in it's tag property.
But, my superiors want a checkbox next to each item. So that they can check each item they want installed. And then have a button which runs the path in each tag property one at a time. It's basically the part where I fill the listview with the checkbox, filename of the exe or msi file, tag and the icon that I'm wondering about.
This is the existing code. This includes just a Tile view of the listview.
Public Sub getDirectories(ByVal strFilepath As String, ByVal strFileExtension As String, ByVal objControl As Object)
'Load first files from the root folder. Then loop each subfolder
Dim di As New DirectoryInfo(strFilepath)
Dim aryFi As IO.FileInfo() = di.GetFiles(strFileExtension, SearchOption.AllDirectories)
Dim filePath As String
Dim fileIcon As Icon
' For each file in the root folder
For Each file In aryFi
If file.Extension = String.Empty Then
Else
filePath = GetAssociatedProgram(file.Extension)
On Error Resume Next
'Extract icon
fileIcon = Drawing.Icon.ExtractAssociatedIcon(filePath)
'Add the icon if we haven't got it already
objControl.StateImageList = Form1.iconList
If Form1.iconList.Images.ContainsKey(filePath) Then
Else
Form1.iconList.Images.Add(filePath, fileIcon)
End If
'Add item to list
objControl.items.add(file.Name, filePath).Tag = file.DirectoryName
End If
Next
End Sub
Basically I call this sub in this way:
getDirectories(strProgramLocation, "*.exe", Form1.listViewSupSoftware)
And I've found that I can add items to a listview which also contains columns:
Dim tempstr(2) As String
tempstr(0) = "Name of item"
tempstr(1) = "Target folder of item"
Dim tempNode As ListViewItem
tempNode = New ListViewItem(tempstr)
Form1.listViewItem.Items.Add(tempNode)
But there should be a way of combining these two right? I'm not sure how I can add a checkbox in the first column of the listview? I've already set the Checkbox property of the listview to True. But I could use some pointers here if anyone's got any. :)
Mmm, I don't understand quite well your question. If you already have the listbox you just need to use a CheckedListBox and loop thru all the checked items executing the executable stored into the tag property ...
As I said I'm not sure If I get what you mean ...