vb.net how I get a list of active and open forms in MDIparent inside MenuStrip Horizontally? - vb.net

Please, How I get a similar Open And Active child forms that are located in the "Windows" ToostripMenuItem in MdiParent as the picture below. but I want them horizontally, is there anyway to that? I appreciate your help.
UPDATE: SOLUTION
I figured out a way to do what I want, and here is the solution
first this code is to add a ToolStripMenuItem to the mdiparent on form_load
Me.MdiParent = MDIParent1
mdf.BackColor = Color.Red
mdf.Text = Me.Text
AddHandler mdf.Click, AddressOf mdf1_Click
MDIParent1.MenuStrip.Items.Add(mdf)
then the ToolStripMenuItem click handler on the form
Private mdf As New ToolStripMenuItem
Private Sub mdf1_Click(ByVal sender As Object, ByVal e As EventArgs)
Me.BringToFront()
End Sub
and this code is to remove the ToolStripMenuItem when the form is closed in (Form_formclosing) event
Try
Dim ParentForm As MDIParent1 = MDIParent1
Dim OptionsMenuStrip As MenuStrip = ParentForm.Controls("MenuStrip")
Dim Items As ToolStripItemCollection = OptionsMenuStrip.Items
Dim removeThese As New List(Of ToolStripMenuItem)
For Each Item As ToolStripMenuItem In Items
If Item.Text = Me.Text Then
removeThese.Add(Item)
End If
Next
For Each item In removeThese
Items.Remove(item)
item.Dispose()
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
and to set the back color to red of the ToolStripMenuItem of the active form in MdiParent_MdiChilActivate event
Private Sub MDIParent1_MdiChildActivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MdiChildActivate
Try
Dim activeChild As Form = Me.ActiveMdiChild
Dim ParentForm As MDIParent1 = Me
Dim OptionsMenuStrip As MenuStrip = ParentForm.Controls("MenuStrip")
Dim Items As ToolStripItemCollection = OptionsMenuStrip.Items
For Each Item As ToolStripMenuItem In Items
If Item.Text = activeChild.Text Then
Item.BackColor = Color.Red
Else
Item.BackColor = Color.LightGray
End If
Next
Catch
End Try
End Sub
and the result: (The active form is the red ToolStripMenuItem):

Related

How to disable and get name for control in FlowLayoutPanel from ContextMenuStrip in VB.Net

My program contains buttons in a FlowLayoutPanel.
I want to disable any button when right click on it and click "Disable" in the ContextMenuStrip.
My code is:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For i As Integer = 0 To 30
Dim btn As New Button
btn.Name = i
btn.Text = i
btn.ContextMenuStrip = ContextMenuStrip1
FlowLayoutPanel1.Controls.Add(btn)
Next
End Sub
End Class
declare a public varibale for keeping a control
public ctrl as button = nothing
you can create a right click by putting this code on mouse down...
If e.Button <> Windows.Forms.MouseButtons.Right Then Return
Dim cms = New ContextMenuStrip
ctrl = sender
Dim item1 = cms.Items.Add("Disable")
item1.Tag = 1
AddHandler item1.Click, AddressOf Disable
end if
and in the diable sub you can code like this...
Private Sub Disable()
ctrl.enabled = false
End Sub

Listview - Drag & Drop cursor to PC desktop

I'm using a function to change my cursor to icon when dragging item from Listview to PC Desktop. Cursor works when I drag item directly from "floating" window to desktop, but It changes when I try to drag It from Listview which is embedded inside another control (which is my case). In another words, when cursor leaves Listview and touches another control on my form (such as Panel), my cursor changes to something like image below:
How could I obtain My cursor same all the way until I drop Item ? Here is my code so far:
Private Sub Listview1_ItemDrag(sender As Object, e As ItemDragEventArgs) Handles Listview1.ItemDrag
Dim Lview As System.Windows.Forms.ListView = DirectCast(sender, System.Windows.Forms.ListView)
Dim filecollection As New ArrayList
If Lview.SelectedItems.Count > 0 Then
For Each myItem In Lview.SelectedItems
If File.Exists(myItem.Tag.ToString) Then
filecollection.Add(myItem.Tag.ToString)
ElseIf Directory.Exists(myItem.Tag.ToString) Then
filecollection.Add(myItem.Tag.ToString)
End If
Next
Dim result = Lview.DoDragDrop(New DataObject(DataFormats.FileDrop, DirectCast(IzbraniPredmeti.ToArray(GetType(String)), String())), DragDropEffects.Copy)
If result = DragDropEffects.Copy Then
Me.Cursor = Cursors.Default
End If
End If
End Sub
Private Sub Listview1_GiveFeedback(sender As Object, e As GiveFeedbackEventArgs) Handles Listview1.GiveFeedback
e.UseDefaultCursors = False
Dim Lview As System.Windows.Forms.ListView = DirectCast(sender, System.Windows.Forms.ListView)
Dim img As New Bitmap(MyImageList.Images(CacheShellIcon(Lview.SelectedItems(0).Tag.ToString)))
Me.Cursor = my_functions.CreateCursor(img) 'function to create cursor
End Sub
Private Sub Listview1_DragOver(sender As Object, e As DragEventArgs) Handles Listview1.DragOver
Dim Lview As System.Windows.Forms.ListView = DirectCast(sender, System.Windows.Forms.ListView)
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
e.Effect = DragDropEffects.Copy
End If
End Sub

How do i assign dynamic controls to a dyanamically created context menu strip?

i have created a dynamic contextmenustrip and added dynamic item to it. How do i assign dynamic controls to it. For example
i have added dynamic item as such
"A1",:"A2","A3"... so on
each value has controls to the flow-layout panel
if i click A1 then the button should be moved from parent panel to the "A1" panel. if i click "A2" it has to go to panel "A2". The no of flow panels are dynamic.
Is this question clear?
Is it possible to assign controls dynamically as well?
Here is the code i did so far
Here i created dynamic menu and adding item
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim pt As New ContextMenuStrip
Dim pt1 As New ContextMenuStrip
Me.ContextMenuStrip = pt
pt.Name = "Cont1"
For Each c As Control In FlowLayoutPanel1.Controls
If TypeOf c Is FlowLayoutPanel Then
array.Add(c.Name)
AddHandler pt.Click, AddressOf contest
End If
Next
Dim data As String
For Each Data In array
pt.Items.Add(data)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Here i want the controls where am having problem
Private Sub contest(sender As Object, e As EventArgs)
Dim pt As New ContextMenuStrip
pt = CType(sender, ContextMenuStrip)
MsgBox(pt.Name)
End Sub
You should use this method:
Control.Controls.Add(control)
so it would be for example:
panelA1.Controls.Add(button1)
Edit:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim pt As New ContextMenuStrip
Dim pt1 As New ContextMenuStrip
Me.ContextMenuStrip = pt
pt.Name = "Cont1"
For Each c As Control In FlowLayoutPanel1.Controls
If TypeOf c Is FlowLayoutPanel Then
array.Add(c.Name)
'AddHandler pt.Click, AddressOf contest
End If
Next
Dim data As String
For Each Data In array
Dim mui As New ToolStripMenuItem(data)
AddHandler mui.Click, AddressOf contest
pt.Items.Add(mui)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Then in contest, ctype sender to toolstripmenuitem instead of contextmenustrip and based on the text you would know whos the caller:
Private Sub contest(sender As Object, e As EventArgs)
Dim mui As New ToolStripMenuItem
mui = CType(sender, ToolStripMenuItem)
MsgBox(mui.Text)
End Sub
Now this creates dynamic contextmenustrip witch gets the flowlayoutpanel avalable in the userforms and moves button from one lowlayoutpanel to the other
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
Dim pt As New ContextMenuStrip
Dim pt1 As New ContextMenuStrip
Me.ContextMenuStrip = pt
pt.Name = "Cont1"
For Each c As Control In FlowLayoutPanel1.Controls
If TypeOf c Is FlowLayoutPanel Then
array.Add(c.Name)
End If
Next
Dim data As String
For Each data In array
Dim mui As New ToolStripMenuItem(data)
AddHandler mui.Click, AddressOf contest
pt.Items.Add(mui)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub contest(sender As Object, e As EventArgs)
Dim mui As ToolStripItem
Dim str As String
mui = CType(sender, ToolStripItem)
str = mui.Text
Dim flo As FlowLayoutPanel = DirectCast(FlowLayoutPanel1.Controls(str), FlowLayoutPanel)
MsgBox(mui.Text)
flo.Controls.Add(Button1)
End Sub

How to customize the click event of dynamically created buttons from string array?

Here is the code I have:
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddNewButton()
End Sub
Public Sub AddNewButton()
Dim buttonTop As Integer = 100
For Each item As String In Globals.candidates
Dim btn As New System.Windows.Forms.Button()
Dim Location As New Point(100, (buttonTop + 20))
btn.Location = Location
btn.Text = item
btn.Width = 150
AddHandler btn.Click, AddressOf Me.buttonClick
Me.Controls.Add(btn)
buttonTop += 20
Next
End Sub
Private Sub buttonClick()
Dim result As Integer = MessageBox.Show(String.Format("Did you select {0} ?", ???????????), "Confirmation", MessageBoxButtons.YesNo)
If result = DialogResult.Yes Then
MessageBox.Show("Yes pressed")
Else
MessageBox.Show("No pressed")
End If
End Sub
End Class
Globals.candidates is a global string array variable that holds a name "LastName, FirstName" and when the form is loaded I call the AddNewButton() Sub and it creates buttons for each item in the string array. No problem.
If you see in my code the "??????????" section, I don't know how to reference the dynamically created buttons's text so that I can display the proper "Did you select thisButton.text" properly.
Any help is appreciated.
Thanks!
EDIT:
Code changed as per suggestions: (Working)
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddNewButton()
End Sub
Public Sub AddNewButton()
Dim buttonTop As Integer = 100
For Each item As String In Globals.candidates
Dim btn As New System.Windows.Forms.Button()
Dim Location As New Point(100, (buttonTop + 20))
btn.Location = Location
btn.Text = item
btn.Width = 150
AddHandler btn.Click, AddressOf Me.buttonClick
Me.Controls.Add(btn)
buttonTop += 20
Next
End Sub
Private Sub buttonClick(sender As Object, e As EventArgs)
Dim btn As Button = DirectCast(sender, System.Windows.Forms.Button)
Dim result As Integer = MessageBox.Show(String.Format("Did you select {0} ?", btn.Text), "Confirmation", MessageBoxButtons.YesNo)
If result = DialogResult.Yes Then
MessageBox.Show("Yes pressed")
Else
MessageBox.Show("No pressed")
End If
End Sub
End Class
You need to put the proper signature on your event handler:
Private Sub buttonClick(sender As Object, e As EventArgs)
Then, you can use the sender object (which will be whichever button was clicked)
Dim button As Button = DirectCast(sender, System.Windows.Forms.Button)
Dim result As Integer = MessageBox.Show(String.Format("Did you select {0} ?", button.Text), "Confirmation", MessageBoxButtons.YesNo)
To get a reference to the button clicked you need to declare the event handler of the button click with the two parameters that are passed to it by the form engine.
Private Sub buttonClick(sender as Object, e as EventArgs)
Now, this correct event handler receives a parameter named sender that is the control reference to the button clicked. You could cast it to a button and then extract the Text property
Private Sub buttonClick(sender as Object, e as EventArgs)
Dim btn = DirectCast(sender, System.Windows.Forms.Button)
if btn IsNot Nothing then
Dim result As Integer = MessageBox.Show(String.Format("Did you select {0} ?", btn.Text), "Confirmation", MessageBoxButtons.YesNo)
If result = DialogResult.Yes Then
MessageBox.Show("Yes pressed")
Else
MessageBox.Show("No pressed")
End If
End If
End Sub
This should be enough in this simple case where you have just a string data, but, if you need to associate a more complex object (like an instance of a Person class for example) you could use the Tag property of every dynamically added button to store there a reference to the instance of the class
As a side note, your code works also without the declaration of the two parameters because you have the Option Strict configuration set to OFF. This is a bad practice because it introduces subtle errors in you parameters usage and in automatic conversions of type. If you are just starting with a new project remember to set its property Option Strict to ON

ContextMenuStrip selected item lost in UserControl

I have a VB.NET User Control which is embedded into another User Control and that into a form. The inner User Control has a contextmenustrip triggered by a DataGridView row click. This successfully activates the event handler (I see the "OK" message), but the sender does not send the selected item (I don't see the other MsgBox messages). Here is the code:
Public CMSV As ContextMenuStrip
Private grdSourceViewerCurrentRow As Long
Public Sub grdSourceViewer_RowHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles grdSourceViewer.RowHeaderMouseClick
'code to review/edit source details
Select Case e.Button
Case Windows.Forms.MouseButtons.Right
grdSourceViewerCurrentRow = e.RowIndex 'retain for downstream code
CMSV = New ContextMenuStrip
AddHandler CMSV.MouseClick, AddressOf SourceViewDocumentationEdit
CMSV.Items.Add("Edit")
CMSV.Items.Add("Transfer to Evidence")
Dim Pt As Point = New Point()
Pt.X = grdSourceViewer.PointToClient(Cursor.Position).X
Pt.Y = grdSourceViewer.PointToClient(Cursor.Position).Y + 20
CMSV.Show(sender, Pt)
Case Windows.Forms.MouseButtons.Left
Exit Sub
Case Else
Exit Sub
End Select
End Sub
Public Sub SourceViewDocumentationEdit()
MsgBox("OK") 'I can see it reaches here
Dim cc As ToolStripItemCollection = CMSV.Items
Dim SelectedItem As Integer = -1
Dim SelectedValue As String = ""
For i As Integer = 0 To cc.Count - 1
If cc.Item(i).Selected Then
SelectedItem = i
SelectedValue = cc.Item(SelectedItem).Text
Exit For
End If
Next
Select Case SelectedValue
Case "Edit"
MsgBox("Edit code here")
Case "Transfer to Evidence"
MsgBox("Transfer code here")
End Select
End Sub
What is wrong here? Why am I losing the info about the item that was clicked?
Why are you recreating the menu each time?
At any rate, store the ToolStripMenuItem returned by CMSV.Items.Add() and wire that up instead.
Simplified example:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
CMSV = New ContextMenuStrip
Dim TSMI As ToolStripMenuItem
TSMI = CMSV.Items.Add("Edit")
AddHandler TSMI.Click, AddressOf TSMI_Click
TSMI = CMSV.Items.Add("Transfer to Evidence")
AddHandler TSMI.Click, AddressOf TSMI_Click
' ...
End Sub
Private Sub TSMI_Click(sender As Object, e As EventArgs)
Dim TSMI As ToolStripMenuItem = DirectCast(sender, toolstripmenuitem)
Select Case TSMI.Text
Case "Edit"
Debug.Print("...Edit Code...")
' use "grdSourceViewerCurrentRow " in here?
Case "Transfer to Evidence"
Debug.Print("...Transfer to Evidence Code...")
' use "grdSourceViewerCurrentRow " in here?
End Select
End Sub
You need to use a ToolStripMenuItem and not just a string. Then you can add the handler for it's click event.
Dim tsmi As New ToolStripMenuItem
tsmi.Text = "Edit"
AddHandler tsmi.Click, AddressOf ItemClicked
CMSV.Items.Add(tsmi)
Then the event sub:
Private Sub ItemClicked(sender As Object, e As EventArgs)
'item clicked
'sender object would be the ToolStripMenuItem
End Sub