Get the selectedvalue for the right clicked row in checkedlistbox

printmedia
printmedia used Ask the Experts™
on
Hi all.

I have a checkedlistbox that I populate via the code below. I also added a ContextMenuStrip that when the end user right clicks a row (regardless if it's checked or not) I want to be able to edit the text. To do this I need to get the SelectedValue but unfortunately with the code below, the SelectedValue (i.e. StepID) is blank.

What am I doing wrong? Thank you in advance.

Private Sub LoadSteps()
CheckedListBox_OpportunitySteps.Items.Clear()

        Dim con As New SqlConnection
        Dim cmd As New SqlCommand

        con.ConnectionString = "Data Source=myserver;Initial Catalog=mydatabase;Integrated Security=True"

        con.Open()

        cmd.Connection = con

        cmd.CommandText = "SELECT Step, Completed, StepID FROM CRMOpportunitySteps WHERE OpportunityID = @OpportunityID ORDER BY StepID"
        cmd.Parameters.AddWithValue("@OpportunityID", opportunityID)

        Dim sda As New SqlDataAdapter(cmd)
        Dim dt As New DataTable()

        sda.Fill(dt)

        CheckedListBox_OpportunitySteps.DisplayMember = "Step"
CheckedListBox_OpportunitySteps.ValueMember = "StepID"

If dt.Rows.Count > 0 Then
            For i As Integer = 0 To dt.Rows.Count - 1
 CheckedListBox_OpportunitySteps.Items.Add(CStr(dt.Rows(i).Item(0)), dt.Rows(i).Item(1))

            Next
 End If
    End Sub

Private Sub EditToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles EditToolStripMenuItem.Click

        
        Dim itm As String

        itm = InputBox("Enter Step", "New Step", CheckedListBox_OpportunitySteps.SelectedItem)

        If itm.Trim <> "" Then UpdateStep(itm)

        LoadSteps()
    End Sub

    Sub UpdateStep(ByVal newItem As String)
        Dim con As New SqlConnection
        Dim cmd As New SqlCommand
        Dim adapter As New SqlDataAdapter()
        Dim ds As New DataSet()

        con.ConnectionString = "Data Source=myServer;Initial Catalog=mydatabase;Integrated Security=True"

        con.Open()

        cmd.Connection = con

        newItem = newItem.Trim()

        cmd.CommandText = "UPDATE CRMOpportunitySteps SET Step = @Step WHERE StepID = @StepID"
        cmd.Parameters.AddWithValue("@StepID", CheckedListBox_OpportunitySteps.SelectedValue)
        cmd.Parameters.AddWithValue("@Step", newItem)

        cmd.ExecuteNonQuery()

        cmd.Dispose()
        con.Close()
    End Sub

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
The DisplayMember and ValueMember are property specifiers.  They indicate the property of the consumed type to locate the expected data.  

Proof of concept:

Form1.vb -
Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Public Class Form1
    Private Sub OnLoad(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim people = Enumerable.Range(0, 15).Select(Function(i) New Person With {.Id = i, .Name = $"Name{i}", .Birthdate = DateTime.Now.AddMonths(-i * 9), .IsWorking = i % 2 == 0 }).ConvertToDataTable()
        CheckedListBox1.DataSource = people
        CheckedListBox1.DisplayMember = "Name"
        CheckedListBox1.ValueMember = "Id"
    End Sub

    Private Sub OnClick(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show($"Currently selected item:{CheckedListBox1.SelectedItem}" +
                $"{Environment.NewLine}Currently selected value: {CheckedListBox1.SelectedValue}")
    End Sub
End Class

Class Person
    Public Property Id() As Integer
    Public Property Name() As String
    Public Property Birthdate() As DateTime
    Public Property IsWorking() As Boolean
    Public Overrides Function ToString() As String
        Return $"{{ Id: {Id}, Name: {Name}, Birthdate: {Birthdate.ToShortDateString()}, IsWorking: {IsWorking} }}"
    End Function
End Class

Module Extensions
    <Extension>
    Public Function ConvertToDataTable(Of T)(ByVal source As IEnumerable(Of T)) As DataTable
        Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(GetType(T))
        Dim table As DataTable = New DataTable()

        For i As Integer = 0 To properties.Count - 1
            Dim [property] As PropertyDescriptor = properties(i)
            If [property].PropertyType.IsGenericType AndAlso [property].PropertyType.GetGenericTypeDefinition().Equals(GetType(Nullable)) Then
                table.Columns.Add([property].Name, [property].PropertyType.GetGenericArguments()(0))
            Else
                table.Columns.Add([property].Name, [property].PropertyType)
            End If
        Next

        Dim values(properties.Count - 1) As Object
        For Each item As T In source
            For i As Integer = 0 To properties.Count - 1
                values(i) = properties(i).GetValue(item)
            Next
            table.Rows.Add(values)
        Next

        Return table
    End Function
End Module

Open in new window

Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.Label1 = New System.Windows.Forms.Label()
        Me.CheckedListBox1 = New System.Windows.Forms.CheckedListBox()
        Me.Button1 = New System.Windows.Forms.Button()
        Me.SuspendLayout()
        '
        'Label1
        '
        Me.Label1.AutoSize = True
        Me.Label1.Location = New System.Drawing.Point(12, 9)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(39, 13)
        Me.Label1.TabIndex = 0
        Me.Label1.Text = "Label1"
        '
        'CheckedListBox1
        '
        Me.CheckedListBox1.FormattingEnabled = True
        Me.CheckedListBox1.Location = New System.Drawing.Point(12, 25)
        Me.CheckedListBox1.Name = "CheckedListBox1"
        Me.CheckedListBox1.Size = New System.Drawing.Size(246, 94)
        Me.CheckedListBox1.TabIndex = 1
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(12, 125)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(246, 23)
        Me.Button1.TabIndex = 2
        Me.Button1.Text = "Get Selected Values"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(270, 159)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.CheckedListBox1)
        Me.Controls.Add(Me.Label1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub

    Friend WithEvents Label1 As Label
    Friend WithEvents CheckedListBox1 As CheckedListBox
    Friend WithEvents Button1 As Button
End Class

Open in new window

Produces the following ouptut -Capture.PNGWhat you should do is set your datasource to the datatable and then set the display member and value member properties; e.g. -
Private Sub LoadSteps()
    Dim con As New SqlConnection
    Dim cmd As New SqlCommand

    con.ConnectionString = "Data Source=myserver;Initial Catalog=mydatabase;Integrated Security=True"

    con.Open()

    cmd.Connection = con

    cmd.CommandText = "SELECT Step, Completed, StepID FROM CRMOpportunitySteps WHERE OpportunityID = @OpportunityID ORDER BY StepID"
    cmd.Parameters.AddWithValue("@OpportunityID", opportunityID)

    Dim sda As New SqlDataAdapter(cmd)
    Dim dt As New DataTable()

    sda.Fill(dt)

    CheckedListBox_OpportunitySteps.DataSource = dt
    CheckedListBox_OpportunitySteps.DisplayMember = "Step"
    CheckedListBox_OpportunitySteps.ValueMember = "StepID"
End Sub

Open in new window

-saige-

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial