How do you get the control that was clicked to open a ContextMenuStrip? - vb.net

I'm using a ContextMenuStrip for multiple controls and I'm trying to figure out the best way to get the control that was actually clicked on to open the Context Menu. The sender just gives the ToolStripMenuItem reference, which has an Owner property that references the ContextMenuStrip, but I cannot figure out how to tell which control the click came from. There must be a simple way to check this, right? I'm checking it in the ToolStripMenuItem's click event.
Friend WithEvents mnuWebCopy As System.Windows.Forms.ToolStripMenuItem
...
Private Sub mnuWebCopy_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuWebCopy.Click
I found a similar post about this, but that mentions using a SourceControl property which I do not see on here.
I'm using Visual Studio 2008, VB.Net winforms.

Private Sub mnuWebCopy_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuWebCopy.Click
Dim myItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
Dim cms As ContextMenuStrip = CType(myItem.Owner, ContextMenuStrip)
MessageBox.Show(cms.SourceControl.Name)
End Sub

Your sender is a ToolStripMenuItem -- cast it.
Its owner is a ContextMenuStrip -- get it.
SourceControl is a property on the ContextMenuStrip and references the last control from which the ContextMenuStrip was displayed.

Private Sub kdgToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles kdgToolStripMenuItem.Click
Dim sms = (sender.GetCurrentParent()).SourceControl.name
MsgBox(sms)
End Sub
'///Faster

Private Sub cmsRightClick_Click(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cmsRightClick.MouseClick
Dim s As String = CType(sender, ContextMenuStrip).GetItemAt(CType(sender, ContextMenuStrip).DisplayRectangle.X, _
CType(sender, ContextMenuStrip).DisplayRectangle.Y + e.Y).Text.Trim()
MsgBox(s)
Select Case s
Case Is = "Select Summary Total"
Dim x = 0
Case Is = "Select Collections"
Dim x = 1
Case Is = "UnSelect"
Dim x = 2
Case Is = "Reconcile"
Dim x = 3
Case Is = "Undo Reconciliation"
Dim x = 4
End Select
End Sub

On VB.NET 2013 this work so fine:
Dim cms As ContextMenuStrip = CType(sender, ContextMenuStrip)
MessageBox.Show(cms.SourceControl.Name)

Related

Dynamic Menustrip access vb.net

I'm adding MenuStrips dynamically based on number of rs232 ports available.
The thing is i want to access the controls text in order to use them in the connection.
Private Sub FormConnection_Load(sender As Object, e As EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
Dim Ports As Array = CType(myPort, Object())
If Ports.Length = 0 Then
MessageBox.Show("No connections available.")
Else
Dim PortsLength As Integer = Ports.Length
For Length As Integer = 0 To PortsLength - 1
Dim Item As New ToolStripMenuItem(Ports(Length).ToString, Nothing, _
New EventHandler(AddressOf MenuCOMclick))
Item.CheckOnClick = True
Item.Name = "COMDYN" + Length.ToString
PortsToolStripMenuItem.DropDownItems.Add(Item)
Next
End If
Now i want to add a Event MenuCOMclick where one of the menus is clicked, all the others are unchecked.
I tried to create an array of controls but the menustrips don't work like that..
How can i do that then ?
Private Sub MenuCOMclick(ByVal sender As Object, ByVal e As EventArgs)
???
???
???
End Sub
Thank you
thats the way to access ToolStripMenuItems in your MenuStrip,
note that if you want to access the sender (the control that was raised the event) you need to cast the sender to the control type.
also you can itterate all ToolStripMenuItems. read my comments, hope it helps.
Private Sub MenuCOMclick(ByVal sender As Object, ByVal e As EventArgs)
' thats how you can check the name of the sender
MsgBox(CType(sender, ToolStripMenuItem).Name)
' thats how you can itterate all ToolStripMenuItem
For Each itm As ToolStripMenuItem In MenuStrip1.Items
For Each Childitm As ToolStripMenuItem In itm.DropDownItems
MsgBox(Childitm.Name) ' show name of the item
' example to access all items properties accept the sender
If Childitm.Name <> CType(sender, ToolStripMenuItem).Name Then
itm.ForeColor = Color.Beige
End If
Next
Next
End Sub

How to get Parent control from context menu item - VB.NET [duplicate]

i am attaching a single context menu to multiple text box. so, i need to get the control name/reference that used to show the context menu.
below is the sample image of my context menu:
Below is the code for green marked "paste" item click event:
Dim objTSMI As ToolStripMenuItem
Dim objCMS As ContextMenuStrip
Dim objTxtBox As System.Windows.Forms.TextBox
objTSMI = CType(sender, ToolStripMenuItem)
objCMS = CType(objTSMI.Owner, ContextMenuStrip)
objTxtBox = CType(objCMS.SourceControl, System.Windows.Forms.TextBox)
If Clipboard.ContainsText(TextDataFormat.Text) = True Then
objTxtBox.SelectedText = Clipboard.GetText(TextDataFormat.Text)
End If
it works very fine.
but below is my code for red marked "Page count" item click event:
Dim objTSMI As ToolStripMenuItem
Dim objCMS As ContextMenuStrip
Dim objTxtBox As System.Windows.Forms.TextBox
objTSMI = CType(sender, ToolStripMenuItem)
objCMS = CType(objTSMI.Owner, ContextMenuStrip)
objTxtBox = CType(objCMS.SourceControl, System.Windows.Forms.TextBox)
MessageBox.Show(objTxtBox.Name)
but above throws following error :
Unable to cast object of type 'System.Windows.Forms.ToolStripDropDownMenu' to type 'System.Windows.Forms.ContextMenuStrip'.
here is the screenshot of the error:
so, i can't figure it out what is the issue.
any help would be highly appreciated
If you check this C# thread the accepted answer notes it is a bug. The workaround presented there uses a private variable to store the SourceControl on the Opening event of the ContextMenuStrip. I've converted to VB.NET and used the Tag of the ContextMenuStrip instead of using the variable. You then refer to the Tag property instead of the faulty SourceControl property:
Imports System.ComponentModel
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.TextBox1.ContextMenuStrip = Me.ContextMenuStrip1
Me.TextBox2.ContextMenuStrip = Me.ContextMenuStrip1
End Sub
Private Sub ContextMenuStrip1_Opening(sender As Object, e As CancelEventArgs) Handles ContextMenuStrip1.Opening
Me.ContextMenuStrip1.Tag = CType(Me.ContextMenuStrip1.SourceControl, Control)
End Sub
Private Sub TestToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles TestToolStripMenuItem.Click
' first level of context menu strip
Dim Strip As ContextMenuStrip = CType(sender, ToolStripMenuItem).Owner
Dim Box As TextBox = Strip.Tag
MessageBox.Show(Box.Name)
End Sub
Private Sub ChildToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ChildToolStripMenuItem.Click
' second level of context menu strip
Dim Strip As ContextMenuStrip = CType(sender, ToolStripMenuItem).OwnerItem.Owner
Dim Box As TextBox = Strip.Tag
MessageBox.Show(Box.Name)
End Sub
End Class
Dim ControlsName as string
Private Sub ContextMenuStrip1_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
ControlsName= ContextMenuStrip1.SourceControl.Name.ToString
End Sub

How to change selected item text in list box at run time?

I tried with code like this:
Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles MyBase.Leave
' This way is not working
ListBox1.SelectedItem = TextBox1.Text
' This is not working too
ListBox1.Items(ListBox1.SelectedIndex) = TextBox1.Text
End Sub
The form is looked like this:
I need to change that list text while user typing in the text box. Is it possible to do that at run time?
You are using the form's leave event MyBase.Leave, so when it fires, it is useless to you.
Try using the TextChanged event of the TextBox instead.
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) _
Handles TextBox1.TextChanged
Make sure to check if an item is actually selected in the ListBox:
If ListBox1.SelectedIndex > -1 Then
ListBox1.Items(ListBox1.SelectedIndex) = TextBox1.Text
End If
Use Double click to select line (item) inside list box and change or modify.
Instead of using text box use ListBox1_MouseDoubleClick event
Private Sub ListBox1_MouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDoubleClick
then add this code inside this event
Dim intIndex As Integer = ListBox1.Items.IndexOf(ListBox1.SelectedItem)
Dim objInputBox As Object = InputBox("Change Item :","Edit", ListBox1.SelectedItem)
If Not objInputBox = Nothing Then
ListBox1.Items.Remove(ListBox1.SelectedItem)
ListBox1.Items.Insert(intIndex, objInputBox)
End If
OR
Dim objInputBox As Object = InputBox("Change Item :","Edit", ListBox1.SelectedItem)
If Not objInputBox = Nothing Then
ListBox1.Items(ListBox1.SelectedIndex) = objInputBox
End If

textbox value not getting another form button click event in winforms

I am working on windows form application and I have two forms. 1 is visitorinfo 2 is vistorexitsign.
In the visitorinfo I have save button, while cliking save button I want to get textboxvalue from vistirexitsign form.
Both forms are running at the same time, I have given code like this in save button of visitor info form:
Private Sub BtnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSave.Click
Dim obj As New VisitorExitsign
Dim vs As String = obj.txtvisitoridExit.Text
Dim Visitorid As String = My.Forms.VisitorExitsign.txtvisitoridExit.Text
But I am always getting here txtvisitoridexit.text value null. Not getting the text value.
What is wrong with my code?
You are creating new instance in every click event.
Dim obj As New VisitorExitsign
So the values are set in the new objects but not in existing object.
So actually you have to refer to existing object of VisitorExitsign.
EDIT:
For example:
You are creating form VisitorExitsign in some method.
So whenever you are creating store its reference in some global variable.
VisitorExitsign obj = new VisitorExitsign
at the place where you are creating form
then in click event use obj and assign text.
When you refer to My.Forms.VisitorExitSign.txtvisitoridExit.Text you are referencing the form itself rather than an instance of the form, if that makes sense. So, you are trying to access the default form rather than one which the user has entered text into.
What you probably want to do is to change
Dim Visitorid As String = My.Forms.VisitorExitsign.txtvisitoridExit.Text`
into
Dim Visitorid As String = obj.txtvisitoridExit.Text
What that will do is make sure that the Visitorid is getting it's value from an instance of VisitorExitSign.
Try Like This
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
Dim forms As FormCollection = Application.OpenForms
For Each form As Form In forms
If form.Name = "VisitorExitsign" Then
Dim vs As String = CType(form, VisitorExitsign).txtvisitoridExit.Text
End If
Next
End Sub
Suggesstion:
frmVX = New VisitorExitsign
frmVX.Location = New Point(781, 0)
frmVX.MdiParent = Me
frmVX.Show()
frmVE = New VisitorInfo()
frmVE.Location = New Point(0, 0)
frmVE.MdiParent = Me
frmVE.Tag=frmVX
frmVE.Show()
Button_Click Event
Dim vs As String = CType(me.Tag, VisitorExitsign).txtvisitoridExit.Text
Hope this will works
create a module
Module modTextValue
Public _textVal As String
End Module
then goto txtvisitoridexit's LostFocus event on your form vistirexitsign
Private Sub txtvisitoridexit_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.LostFocus
_textVal = txtvisitoridexit.Text
End Sub
on btnSave'click
Private Sub BtnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSave.Click
Dim str As String
str = _textVal
End Sub
Try this :
in button save update your code to :
Private Sub BtnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSave.Click
Dim obj As New VisitorExitsign
obj.ShowDialog()
Dim vs As String = obj.txtvisitoridExit.Text
End sub
when you close VisitorExitsign, the variable vs will take the value of obj.txtvisitoridExit

Winforms ListBox Control Not Updating After Source Changes

I have a ListBox (LB) with a DataTable (DT) DataSource in the Form Class globally populated in the Form_Load event.
Private Sub frmEditPresets_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
DT.Columns.Add("DisplayText")
DT.Columns.Add("PresetID")
For Each TSI As ToolStripItem In Presets.DropDownItems
If TSI.Name.IndexOf("preset_") > -1 Then
DT.Rows.Add(TSI.Text, TSI.Name)
End If
Next
LB.DataSource = DT
LB.DisplayMember = "DisplayText"
End Sub
When I use my Rename button. It updates the menu item and the Data Source but the Listbox doesn't refresh until I click another item in the listbox.
Rename code:
Private Sub btnRename_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRename.Click
Dim R As DataRowView = LB.SelectedItem
Dim S As String = InputBox("Preset Name", "Rename", R("DisplayText"))
If S.Trim.Length = 0 Then Exit Sub
If Presets.DropDownItems.ContainsKey(R("PresetID").ToString) Then
Presets.DropDownItems(R("PresetID").ToString).Text = S
End If
R("DisplayText") = S
End Sub
I'm sure this is a simple question with a simple answer but I can't seem to figure it out. I've tried Refresh(). I've tried setting the DataSource again. I read this StackOverflow question Winforms listbox not updating when bound data changes but ResetBindings() doesn't seem to be an available method in this context.
*Edit. I gave Steve credit for the answer as he mentioned BindingContext. Although, that led me to find BindingContext(DT).EndCurrentEdit() which updated my LB display and maintained the selection.
Tried with this, and it works.....
Private Sub btnRename_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRename.Click
Dim R As DataRowView = LB.SelectedItem
Dim S As String = InputBox("Preset Name", "Rename", R("DisplayText"))
If S.Trim.Length = 0 Then Exit Sub
If Presets.DropDownItems.ContainsKey(R("PresetID").ToString) Then
Presets.DropDownItems(R("PresetID").ToString).Text = S
End If
R("DisplayText") = S
BindingContext(DT).EndCurrentEdit()
End Sub