ListView right clicking VB.Net - vb.net

So I have my code, and it's kind of working... It shows the contextmenu on the listview when I right click, but I don't think the select case is working, when I click on either edit or delete, nothing happens. Here's my code
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
ComboBox1.SelectedItem = "TRUE"
Dim ctx As New ContextMenu
Dim i1 As New MenuItem("&Edit")
Dim i2 As New MenuItem("&Delete")
AddHandler i1.Click, AddressOf ContextMenuHandler
AddHandler i2.Click, AddressOf ContextMenuHandler
ctx.MenuItems.Add(i1)
ctx.MenuItems.Add(i2)
Me.ListView1.ContextMenu = ctx
End Sub
Private Sub ContextMenuHandler(ByVal Sender As Object, ByVal e As EventArgs)
Dim mi As MenuItem = DirectCast(sender, MenuItem)
Select Case mi.Text.ToLower()
Case "edit"
ListViewToText()
Case "delete"
Try
If ListView1.SelectedItems.Count > 0 Then
ListView1.Items.Remove(ListView1.SelectedItems(0))
End If
Catch ex As Exception
End Try
End Select
End Sub
Thank you!

The Select Case block isn't working because the text is "&edit" and "&delete". The & will appear as part of the Text property.
Note that if you are going to customize the ContextMenuHanndler function for every item that is clicked then a better strategy is to just have a different handler for each one
AddHandler i1.Click, AddressOf EditHandler
AddHandler i2.Click, AddressOf DeleteHandler
Private Sub EditHandler(ByVal Sender As Object, ByVal e As EventArgs)
ListViewToText()
End Sub
Private Sub DeleteHandler(ByVal Sender As Object, ByVal e As EventArgs)
Try
If ListView1.SelectedItems.Count > 0 Then
ListView1.Items.Remove(ListView1.SelectedItems(0))
End If
Catch ex As Exception
End Try
End Sub

Dim i1 As New MenuItem("&Edit")
Dim i2 As New MenuItem("&Delete")
Private Sub ContextMenuHandler(ByVal Sender As Object, ByVal e As EventArgs)
Dim mi As MenuItem = DirectCast(sender, MenuItem)
Select Case mi.Text.ToLower()
Case "edit"
ListViewToText()
Case "delete"
Try
If ListView1.SelectedItems.Count > 0 Then
ListView1.Items.Remove(ListView1.SelectedItems(0))
End If
Catch ex As Exception
End Try
End Select
Change the Case name from "Edit" to "&Edit" same as the declared name above..

Related

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

How to handle a variable amount of buttons clicked?

I have a pretty basic problem with button clicks in VB.Net I cannot seem to figure out.
First, I am creating a variable amount of buttons and adding them to the parent form.
Private Sub CreateUIObjects()
For i As Integer = 1 To NumberOfButtons
Dim button As Button = New Button()
Me.Controls.Add(button)
Next
End Sub
I know it is possible to handle a fixed amount of buttons clicked with the following code
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click, Button2.Click, Button3.Click '... And so on
Dim b As Button = CType(sender, Button)
End Sub
But what do I do with not 3, but a variable amount of buttons?
Some code to experiment with
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
CreateUIObjects(3)
End Sub
Dim myButtonNames As String = "foobar"
Private Sub myButtonsClick(sender As Object, e As EventArgs)
Dim b As Button = DirectCast(sender, Button)
Debug.WriteLine(b.Name)
End Sub
Private Sub CreateUIObjects(NumberOfButtons As Integer)
Static ct As Integer = 0
For i As Integer = 1 To NumberOfButtons
ct += 1
Dim btn As Button = New Button()
btn.Name = myButtonNames & ct.ToString
btn.Text = btn.Name
btn.Location = New Point(ct * 20, ct * 20)
AddHandler btn.Click, AddressOf myButtonsClick
Me.Controls.Add(btn)
Next
End Sub
You can use something like this
AddHandler Button1.Click, AddressOf Button_Click
take a look http://msdn.microsoft.com/en-us/library/ms172877.aspx

Adding 150,000 records to a listview without freezing UI

I have a listview loop that is adding 150,000 items to my listview. For testing purposes I moved this code to a background worker with delegates, but it still freezes up the UI. I am trying to find a solution so that it can add these items in the background while I do other stuff in the app. What solutions do you guys recommend?
this is what I am using
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.Clear()
ListView1.BeginUpdate()
bw.WorkerReportsProgress = True
bw.RunWorkerAsync()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If bw.IsBusy Then bw.CancelAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
For x = 1 To 125000
Dim lvi As New ListViewItem("Item " & x)
If bw.CancellationPending Then
e.Cancel = True
Exit For
Else
bw.ReportProgress(0, lvi)
End If
Next
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bw.ProgressChanged
Try
Dim lvi As ListViewItem = DirectCast(e.UserState, ListViewItem)
Me.ListView1.Items.Add(lvi)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
ListView1.EndUpdate()
If Not e.Cancelled Then
Debug.Print("Done")
Else
Debug.Print("Cancelled")
End If
End Sub
End Class
Give this a try, it's a great example for what you would need... I also had a progress bar that shows the progress and such, see example image that is attached. Also I wasn't seeing any delegate that you need to perform such operation, mine has one that will be required. The reason is you are adding items to a control on the UI thread, in order to add items we need to know if an Invoke is required, if so we invoke otherwise we add the item to the control... Also I made the thread sleep, so it can take a break; this also prevents the UI from wanting to lock up here and there, now it's responsive with NO FREEZING.
Option Strict On
Option Explicit On
Public Class Form1
Delegate Sub SetListItem(ByVal lstItem As ListViewItem) 'Your delegate..
'Start the process...
Private Sub btnStartProcess_Click(sender As Object, e As EventArgs) Handles btnStartProcess.Click
lvItems.Clear()
bwList.RunWorkerAsync()
End Sub
Private Sub AddListItem(ByVal lstItem As ListViewItem)
If Me.lvItems.InvokeRequired Then 'Invoke if required...
Dim d As New SetListItem(AddressOf AddListItem) 'Your delegate...
Me.Invoke(d, New Object() {lstItem})
Else 'Otherwise, no invoke required...
Me.lvItems.Items.Add(lstItem)
End If
End Sub
Private Sub bwList_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwList.DoWork
Dim intCount As Integer = CInt(txtCount.Text)
Dim dblPercent As Integer = 100
Dim intComplete As Integer = 0
Dim li As ListViewItem = Nothing
For i As Integer = 1 To CInt(txtCount.Text)
If Not (bwList.CancellationPending) Then
li = New ListViewItem
li.Text = "Item " & i.ToString
AddListItem(li)
Threading.Thread.Sleep(1) 'Give the thread a very..very short break...
ElseIf (bwList.CancellationPending) Then
e.Cancel = True
Exit For
End If
intComplete = CInt(CSng(i) / CSng(intCount) * 100)
If intComplete < dblPercent Then
bwList.ReportProgress(intComplete)
End If
If li IsNot Nothing Then
li = Nothing
End If
Next
End Sub
Private Sub bwList_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bwList.ProgressChanged
pbList.Value = e.ProgressPercentage
End Sub
Private Sub bwList_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwList.RunWorkerCompleted
If pbList.Value < 100 Then pbList.Value = 100
MessageBox.Show(lvItems.Items.Count.ToString & " items were added!")
End Sub
Private Sub btnStopWork_Click(sender As Object, e As EventArgs) Handles btnStopWork.Click
bwList.CancelAsync()
End Sub
Private Sub btnRestart_Click(sender As Object, e As EventArgs) Handles btnRestart.Click
pbList.Value = 0
lvItems.Items.Clear()
txtCount.Text = String.Empty
End Sub
End Class
Screenshot in action...

open selected row in datagridview to edit in Another form

I am using vb.net designer to connect to access database .
On my Form1 I have a DataGridView And Two Button For Add And Edit
I Make Form2 To Add Data Into Database And Worked OK ..
Imake Form3 Wiht Same form2 Content
Now I need When i selcet row in DataGridView And Clic Edit Button The data of selected row show on form3 for Edit it
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.SalesTableAdapter.Fill(Me.OrdersDataSet.sales)
Me.DateTimePicker1.Value = Date.Today
End Sub
Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
SalesBindingSource.Filter = String.Format("date = '{0}'", DateTimePicker1.Value.ToShortDateString())
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.Show()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form3.Show()
End Sub
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
End Sub
Private Sub SalesDataGridView_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles SalesDataGridView.CellContentClick
End Sub
End Class
You need to approach this in a modal/dialog way. You only need one form for both add and edit.
Add/Edit form
Add a parameterized constructor to the form.
Public Sub New(row As DataRowView)
Me.InitializeComponent()
'Me.ctlAge: NumericUpDown control.
'Me.ctlBirthday: DateTimePicker control.
'Me.ctlName: TextBox control.
If (row Is Nothing) Then
'Add mode, set default values:
Me.ctlAge.Value = 0
Me.ctlBirthday.Value = Date.Now
Me.ctlName.Text = String.Empty
Else
'Edit mode, set current values:
Me.ctlAge.Value = CDec(row.Item("AGE"))
Me.ctlBirthday.Value = CDate(row.Item("BIRTHDAY"))
Me.ctlName.Text = CStr(row.Item("NAME"))
End If
End Sub
You also need an accept button and a cancel button.
Friend Sub btnAcceptClicked(sender As Object, e As EventArgs) Handles btnAccept.Click
Me.DialogResult = Windows.Forms.DialogResult.OK
Me.Close()
End Sub
Friend Sub btnCancelClicked(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.DialogResult = Windows.Forms.DialogResult.Cancel
Me.Close()
End Sub
Main form
Add method:
Private Sub btnAddClicked(sender As Object, e As EventArgs) Handles btnAdd.Click
Try
Using f As New AddOrEditForm(CType(Nothing, DataRowView))
If (f.ShowDialog() = Windows.Forms.DialogResult.OK) Then
Dim view As DataView = TryCast(Me.SalesDataGridView.DataSource, DataView)
If (view Is Nothing) Then
Throw New InvalidCastException()
End If
Dim viewRow As DataRowView = view.AddNew()
viewRow.EndEdit()
viewRow.Item("AGE") = f.ctlAge.Value
viewRow.Item("BIRTHDAY") = f.ctlBirthday.Value
viewRow.Item("NAME") = f.ctlName.Text
viewRow.EndEdit()
End If
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Edit method:
Private Sub btnEditClicked(sender As Object, e As EventArgs) Handles btnEdit.Click
Try
Me.SalesDataGridView.EndEdit()
If (Me.SalesDataGridView.SelectedRows.Count > 0) Then
Dim gridRow As DataGridViewRow = Me.SalesDataGridView.SelectedRows(0)
Dim viewRow As DataRowView = TryCast(gridRow.DataBoundItem, DataRowView)
If (viewRow Is Nothing) Then
Throw New InvalidCastException()
End If
Using f As New AddOrEditForm(viewRow)
If (f.ShowDialog() = Windows.Forms.DialogResult.OK) Then
viewRow.BeginEdit()
Try
viewRow.Item("AGE") = f.ctlAge.Value
viewRow.Item("BIRTHDAY") = f.ctlBirthday.Value
viewRow.Item("NAME") = f.ctlName.Text
viewRow.EndEdit()
Catch ex As Exception
viewRow.CancelEdit()
Throw ex
End Try
End If
End Using
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

Exposing DataGridViewComboBoxEditingControl

I would like to know how to use the DataGridViewComboBoxEditingControl with vb.net
i need a routteen to run when the user select an item from the datagridviewcomboboxcolumn that i have configured. I am unsure how to attach the object to the column i create manually
I have implemented the following from examples on the internet but this only appears to trigger when the user click on the combobox within the column.
Private Sub dgvTicketDetail_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgvTicketDetail.EditingControlShowing
Dim editingComboBox As ComboBox = TryCast(e.Control, ComboBox)
If editingComboBox IsNot Nothing Then
AddHandler editingComboBox.SelectedValueChanged, AddressOf EditingComboBox_DropDown
End If
End Sub
Private Sub EditingComboBox_DropDown(ByVal sender As System.Object, ByVal e As System.EventArgs)
Debug.WriteLine("A ComboBox in the DataGridView just dropped down.")
End Sub
any help would be appreciated as i cant seem to find much reference material for this
Thanks in advance
Just realised that i have never posted the answer to my question
Placed the following in the EditingControlShowing to capture request
Private Sub dgvTicketDetail_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgvTicketDetail.EditingControlShowing
Try
If dgvTicketDetail.CurrentCell.ColumnIndex = 1 Then
Dim cmbox As ComboBox = TryCast(e.Control, ComboBox)
AddHandler cmbox.SelectionChangeCommitted, AddressOf Update_StockInfo
strSelectedText = cmbox.SelectedText
End If
Catch ex As Exception
End Try
End Sub
then this added items to the combobox cell
Private Sub Update_StockInfo(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim cmbClickedCell = DirectCast(sender, DataGridViewComboBoxEditingControl)
Dim cmbComboBox = DirectCast(sender, ComboBox)
If dgvTicketDetail.CurrentRow.Index = cmbClickedCell.EditingControlRowIndex And dgvTicketDetail.CurrentCell.ColumnIndex = 1 Then
Debug.WriteLine(cmbClickedCell.EditingControlRowIndex & cmbComboBox.SelectedValue)
Dim dtStock As DataTable = CropTrackMod.GetWeight(cmbComboBox.SelectedValue)
Dim dgvcc As DataGridViewComboBoxCell
dgvcc = dgvTicketDetail.Rows(cmbClickedCell.EditingControlRowIndex).Cells(2)
dgvcc.Items.Clear()
For Each row As DataRow In dtStock.Rows
dgvcc.Items.Add(row.Item("UnitName"))
Next row
If CropTrackMod.IsStockVATAble(cmbComboBox.SelectedValue) = True Then
dgvTicketDetail.Rows(cmbClickedCell.EditingControlRowIndex).Cells("VATRate").Value = CropTrackMod.dblVATRate
Else
dgvTicketDetail.Rows(cmbClickedCell.EditingControlRowIndex).Cells("VATRate").Value = "0.00"
End If
End If
End Sub
It works really well for me, unfortunately the user wanted something different in the end ha. Oh well at least i learnt something