У меня есть список, в котором есть описание и значение, сохраненное в нем (описание - это имя клиента, а valueitem - это идентификатор клиента в базе данных). В моей форме у меня есть два списка, один из которых имеет полный список клиентов. Затем имена и пользователь выбирают из этого списка и добавляют те, с которыми они хотят связать пользователя, в правый список. Когда я прихожу, чтобы сохранить запись, я хочу сохранить список идентификаторов клиентов в таблице, чтобы я мог определить, к каким клиентам относится эта запись.

Мой код проходит по списку, используя цикл For .. Next:

For n = 0 To lbxCustomerList.Items.Count - 1
  U.CustomersLinkedTo += lbxCustomerList.Items(n).Value.ToString() & ","
Next

U - это класс записей пользователя, а поле CustomersLinkedTo - это поле NVarchar (255), для которого я создам разделенный запятыми список идентификаторов CustomerID, которым пользователь назначил этого пользователя.

Проблема в том, что lbxCustomerList.Items (n) .Value не допускается. Я использую VB.NET и Dot Net Framework V4.

Я попытался загрузить ListBox в переменную ListBox.ObjectCollection, а затем посмотреть, позволяет ли мне получить доступ к ValuItems, но это тоже не позволяет. Как я могу получить значения в отличие от текста описания?

РЕДАКТИРОВАТЬ **** Чтобы помочь тем хорошим людям, которые пытаются мне помочь, я добавляю ниже код, который я использую для заполнения списка клиентов, а затем код, который я использую для заполнения lbxCustomersLinkedTo, который содержит выбранных ими клиентов:

Заполните список слева, из которого пользователь выбирает имена клиентов, и добавляет их в список справа, который содержит подмножество, которое пользователь хочет выделить пользователю.

    Private Sub PopulateCustomerList()
    Dim c As New Customer()
    Dim cc As New ArrayList()

    Try
        'Clear list
        lbxCustomerList.Items.Clear()
        lbxCustomerList.DataSource = Nothing

        'Populate from DB.
        cc = c.GetCustomersForDropLists(customerTypeEnum.Active)
        lbxCustomerList.DataSource = cc
        lbxCustomerList.DisplayMember = "DisplayedText"
        lbxCustomerList.ValueMember = "ReturnedID"
        lbxCustomerList.Refresh()

    Catch ex As Exception
        PEH("PopulateCustomerList", "frmUserSetup", ex.Message)
    End Try
End Sub

Код, который добавляет элементы, которые пользователь выбирает из списка «Клиенты», к тому, который меня интересует, и который я использую для создания списка «Идентификатор клиента», который я хочу добавить в запись своего пользователя.

   Private Sub AddToList()
    Dim SelItems As New ListBox.SelectedObjectCollection(lbxCustomerList)
    SelItems = lbxCustomerList.SelectedItems

    Try

        If lbxCustomerList.SelectedItems.Count > 0 Then
            For n = 0 To SelItems.Count - 1
                lbxCustomersLinkedTo.Items.Add(SelItems(n))
            Next
            lbxCustomerList.ClearSelected()
        End If

    Catch ex As Exception
        PEH("AddToList", "frmUserSetup", ex.Message)
    End Try
End Sub

Это изображение той части формы пользователя, о которой я говорю: Выбор части экрана для клиентов

@ThePeter - Спасибо, ваша рутина с небольшими изменениями сделала свое дело.

Это мой код в процедуре сохранения сейчас:

           'Get the Customers an officer works for into a comma separated list.
        'First remove any existing items.
        U.CustomersLinkedTo = ""

        If (lbxCustomersLinkedTo.Items.Count > 0) Then
            For n = 0 To lbxCustomersLinkedTo.Items.Count - 1
                If n = lbxCustomersLinkedTo.Items.Count - 1 Then
                    U.CustomersLinkedTo += WhatValueIsSelectedInListBoxForIndex(lbxCustomersLinkedTo, n) 'Don't add comma to last item.
                Else
                    U.CustomersLinkedTo += WhatValueIsSelectedInListBoxForIndex(lbxCustomersLinkedTo, n) & ","
                End If
            Next
        End If

Это ваша процедура слегка изменена, так как изначально выдает ошибку:

   ''' <summary>
''' Use this function to get the values of an item in the list box. It works with list boxes that are bound to a DataSet, and those that have been populated via code, or manually populated via the GUI.
''' </summary>
''' <param name="lstBox">The list box you want to find the selected value in.</param>
''' <param name="iIndex">The number of the item in the ListBox that you want the value for.</param>
''' <param name="DesiredReturnValue">By default it returns the hidden return value, but you can ask for the display value if desired.</param>
''' <returns>This function returns a String value.</returns>
Public Function WhatValueIsSelectedInListBoxForIndex(ByVal lstBox As ListBox, ByVal iIndex As Integer, Optional ByVal DesiredReturnValue As SelectByMode = SelectByMode.ByReturnValue) As String
    Dim sReturn As String = ""

    Try
        If DesiredReturnValue = SelectByMode.ByReturnValue Then
            'Returns the value that is not visible, but stored in the "ValueMember" field of the bound ComboBox
            If lstBox.ValueMember.Length > 0 And lstBox.DisplayMember.Length > 0 Then
                'This is a bound listbox.
                Dim drSelectedItem As DataRowView = lstBox.Items(iIndex)
                sReturn = drSelectedItem.Item(0).ToString
            Else
                Try
                    'This listbox was populated in code with display values and return values.
                    sReturn = lstBox.Items(iIndex).ReturnedID
                Catch ex As Exception
                    PEH("WhatValueIsSelectedInListBoxForIndex - Populated Code section", "frmUserSetup", ex.Message)
                End Try
            End If
        ElseIf DesiredReturnValue = SelectByMode.ByDisplayName Then
            'Return the selected TEXT (visible in the control)
            If lstBox.ValueMember.Length > 0 And lstBox.DisplayMember.Length > 0 Then
                'This is a bound listbox.
                Dim drSelectedItem As DataRowView = lstBox.Items(iIndex)
                sReturn = drSelectedItem.Item(1).ToString
            Else
                sReturn = lstBox.Items(iIndex).ToString
            End If
        Else
            sReturn = ""
        End If
    Catch Ex As Exception

        PEH("WhatValueIsSelectedInListBoxForIndex", "frmUserSetup", Ex.Message)
        sReturn = ""
    End Try

    If sReturn Is Nothing Then sReturn = ""
    Return sReturn

End Function

Бит, который я должен был изменить, чтобы он соответствовал моему списку, был строкой:

                       'This listbox was populated in code with display values and return values.
                    sReturn = lstBox.Items(iIndex).ReturnedID

С вашей помощью это теперь работает и заполняет поле базы данных напрямую.

Сив

1
Siv 29 Май 2019 в 17:06

2 ответа

Лучший ответ

Эта функция позволит вам найти значение того, что выбрано в ListBox. Вы можете использовать его для получения «скрытого» значения выбранного элемента или отображаемого значения элемента в ListBox.

Обновление: я настроил функцию так, чтобы она работала на основе значения индекса согласно исходному вопросу

Public Enum SelectByMode As Integer
   ByDisplayName = 1
   ByReturnValue = 2
End Enum

''' <summary>
''' Use this function to get the values of an item in the list box. It works with list boxes that are bound to a DataSet, and those that have been populated via code, or manually populated via the GUI.
''' </summary>
''' <param name="lstBox">The list box you want to find the selected value in.</param>
''' <param name="iIndex">The number of the item in the ListBox that you want the value for.</param>
''' <param name="DesiredReturnValue">By default it returns the hidden return value, but you can ask for the display value if desired.</param>
''' <returns>This function returns a String value.</returns>
Public Function WhatValueIsSelectedInListBoxForIndex(ByVal lstBox As ListBox, ByVal iIndex As Integer, Optional ByVal DesiredReturnValue As SelectByMode = SelectByMode.ByReturnValue) As String
    Dim sReturn As String = ""

    Try
        If DesiredReturnValue = SelectByMode.ByReturnValue Then
            'Returns the value that is not visible, but stored in the "ValueMember" field of the bound ComboBox
            If lstBox.ValueMember.Length > 0 And lstBox.DisplayMember.Length > 0 Then
                'This is a bound listbox.
                Dim drSelectedItem As DataRowView = lstBox.Items(iIndex)
                sReturn = drSelectedItem.Item(0).ToString
            Else
                Try
                    'This listbox was populated in code with display values and return values.
                    sReturn = lstBox.Items(iIndex).ReturnValue
                Catch Exp As Exception
                    '
                End Try
            End If
        ElseIf DesiredReturnValue = SelectByMode.ByDisplayName Then
            'Return the selected TEXT (visible in the control)
            If lstBox.ValueMember.Length > 0 And lstBox.DisplayMember.Length > 0 Then
                'This is a bound listbox.
                Dim drSelectedItem As DataRowView = lstBox.Items(iIndex)
                sReturn = drSelectedItem.Item(1).ToString
            Else
                sReturn = lstBox.Items(iIndex).ToString
            End If
        Else
            sReturn = ""
        End If
    Catch Exp As Exception
        'You do whatever you want to do here when an error occurs.
    End Try

    If sReturn Is Nothing Then sReturn = ""
    Return sReturn
End Function
2
ThePeter 29 Май 2019 в 18:57

Удалите часть .Value или используйте этот код вместо

For n = 0 To lbxCustomerList.Items.Count - 1
  U.CustomersLinkedTo += lbxCustomerList.Items(n).ToString() & ","
Next

Еще проще, вы можете использовать то, что @LarsTech сказал, что это не потребует цикла

U.CustomersLinkedTo = String.Join(", ", lbxCustomerList.Items)
1
Ess Kay 29 Май 2019 в 15:03