【问题标题】:Unable to set valuemember/display member to bind combobox无法设置值成员/显示成员以绑定组合框
【发布时间】:2014-05-14 00:20:19
【问题描述】:

我在向我的 datagridview 动态添加组合框列时遇到问题(在您询问之前,是的,它必须是动态的,而不是在编辑器中完成)。

主要特点是每行的组合框单元格不同,所以必须使用组合框单元格来完成。 checkedRows 是一个数据表。

datagridview 的名称是editCameraTable。此时它已经有几列:

'create new column
            Dim resComboColumn As New DataGridViewComboBoxColumn _
                With {.HeaderText = "Resolution", .ReadOnly = False, .DisplayIndex = 7, .Name = "Resolution", _
                      .DisplayMember = "Name", .ValueMember = "ID", .DataPropertyName = "ID"}

           'add combo box column 

            EditCameras.editCameraTable.Columns.Insert(17, resComboColumn)
            addResCmbBox(checkedRows, resComboColumn)

非常直接。您会注意到我有值成员、数据属性名称等。这是 addResCmbBox 定义:

Public Function addResCmbBox(ByRef DT As DataTable, column As DataGridViewComboBoxColumn)

    Dim resolutions As String()
    'for each camera 
    For i As Integer = 0 To DT.Rows.Count - 1

        Dim camera As camera = convertDTtoCam(DT, i)

        'get the resarray 
        Select Case DT.Rows(i).Item("Maker").ToString.ToLower

            Case "acti"
                resolutions = ACTi.GetResArray(camera)
            Case Else
                resolutions = ACTi.GetResArray(camera)
        End Select

        'add items to combobox list 
        Dim comboCell As New DataGridViewComboBoxCell

        comboCell.DataSource = resolutions

        For j As Integer = 0 To resolutions.Length - 1

            'set to current resolution value
            If resolutions(j).TrimStart("N") = camera.res Then
                comboCell.Value = resolutions(j)

            End If

        Next
        comboCell.DisplayMember = "Name"
        comboCell.ValueMember = "ID"
        EditCameras.editCameraTable("Resolution", i) = comboCell


    Next
    Return Nothing
End Function

相机是一个结构。在我遇到 displayMember 和 value 成员问题之前,我没有任何问题,即最后一行以“editcameras.editcameratable ...”开头。

这样做时会弹出“字段名称不存在”的异常。如果我不分配 displayMember 和 valueMember,我没有问题。但是,我无法获得在组合框中选择的值(它返回为 Null)。在运行时,组合框列的值成员和显示名称为“ID”和“名称”。

如何将此组合框单元格绑定到该行,以便稍后获得它的选定值?

更新:

我按照评论做了,并创建了一个结构/类作为分辨率属性:

 Public Class ResolutionStruct
 Property Name As String
 Property ID As String
 End Class

在循环中,我创建了一个此类的列表,并将值分配给它:

      Dim resolutionList As New List(Of ACTi.ResolutionStruct)

        For j As Integer = 0 To resolutions.Length - 1

            Dim resClass As New ACTi.ResolutionStruct
            resClass.Name = resolutions(j)
            resClass.ID = resolutions(j)
            resolutionList.Add(resClass)


        Next

        'set combocell values
        comboCell.DisplayMember = "Name"
        comboCell.ValueMember = "ID"
        comboCell.DataSource = resolutionList

        EditCameras.editCameraTable("Resolution", i) = comboCell

但是,comboboxCell 在下拉时不显示任何值。所以,现在我已经绑定了这些值,但它什么也没显示。还有什么我应该做的,这样我就可以看到我正在选择的值并将它们绑定到数据网格视图的神圣组合? :D

更新 2 所以,认错。我将组合框单元格添加到错误的列!

所以现在,它正在显示值。我单击一个值,并尝试将选定的值作为字符串抓取:

  Dim cmbbox2 As DataGridViewComboBoxCell = editCameraTable("Resolution", i)
                 resolution(i) = cmbbox2.Selected.ToString()

但它仍然说它是一个空值!中期构建我检查了组合框道具。事实上,“选择”是一个布尔值作为假。它没有价值,说它也没有物品。关于为什么它说它为空的任何想法?

UPDATE3

我最近在表格中使用了不同的列,组合框中的值被清除了!我想它真的从来没有被附加/绑定在首位。

UPDATE4

修好了!!

显然这一行: editCameraTable.Sort(editCameraTable.Columns("ID"), System.ComponentModel.ListSortDirection.Ascending)

把桌子吓坏了!我现在可以得到值了(哇哦!)

【问题讨论】:

  • 是名称和 ID 属性吗?因此:属性名称为字符串,而不是公共名称为字符串
  • 我不明白你在说什么。我也将 displayMember 和 valuemember 设置为“Resolution”,它会说属性字段不存在(单独完成)。
  • 啊,我的错,我认为您将相机对象添加到组合框。没有通读它以意识到您正在添加一个字符串数组。所以忽略我的第一条评论,我会看看我是否可以帮助你。

标签: vb.net datagridview combobox


【解决方案1】:

好的,我会尽快解释一下:

DisplayMember 和 ValueMember 应该使用属性来设置。例如,您创建一个包含名称和 ID 的类

Public Class Test
  Property Name as String
  Property ID as String
End Class

创建一些这样的对象并将它们放在一个列表中。将列表设置为组合框的数据源。现在您可以访问在代码中编写的 DisplayMember 和 ValueMember。值是 ID,SelectedItem 是整个类。

您现在所做的是将字符串列表添加到组合框中。字符串不包含属性名称或 ID,因此您自然无法获取它们。像这样看:

为了能够使用 Value 和/或 DisplayMember,您需要能够自己获取属性。在这种情况下:

resolutions(j).Name 
or 
resolutions(j).ID

这不起作用。

但是例如你可以这样做:

resolutions(j).Length

所以你可以这样做,这将在组合框中显示长度:

Combobox.DisplayMember = "Length"

目前要获得你必须做的价值:

Combobox.SelectedItem.ToString()

但是由于您将它放在组合框列中,我的猜测是这不会削减它,因为您无法从 DataGridView 中获取值。

编辑:你还在这样做吗?

<DataGridView>.Item("Resolution", i) = comboCell

否则您将有空的组合框。

EDIT2:无需从 Combobox 中获取值,而是从 Grid 单元格中获取:

<DataGridView>.Item("Resolution", i).Value

在创建列的时候不要忘记给组合框设置一个默认值,否则它可能是Nothing:

comboCell.DisplayMember = "Name"
comboCell.ValueMember = "ID"
comboCell.Value = resolutions(0)

【讨论】:

  • 啊,我明白你在这里想说什么了。是的,基本上问题是值永远不会绑定到dataGridView。您是否建议我在创建列之前声明 Name 和 ID 属性,然后使用相同的代码来获取值?还是我需要将这些属性添加到分辨率数组/创建分辨率结构?
  • 为每个分辨率创建一个类项(测试)。将 name 和 id 设置为 resolution(j)。然后将类列表作为数据源,你应该没问题。
  • 是的,EditCameras.editCameraTable("Resolution", i) = comboCell 在我设置了值成员之后。我也做了网格单元,仍然是一个空异常。我将它添加到问题代码中。
  • 这将返回一个空字符串:Dim x As String = editCameraTable.Rows(0).Cells("Resolution").Value。附:到目前为止,您的帮助非常好。
  • 添加 'comboCell.Value = resolutions(0)' 不走运。它确实将组合框单元的值类型返回为“System.Object”,并且 value.string 为“Nothing”。我将编辑问题以显示我所做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 2016-09-05
  • 1970-01-01
相关资源
最近更新 更多