【问题标题】:DataGridView combo boxDataGridView 组合框
【发布时间】:2008-10-26 19:07:04
【问题描述】:

如何访问 DataGridView 中特定行中组合框的项目集合?

我正在按如下方式填充组合:

          Dim VATCombo As New DataGridViewComboBoxColumn
            With VATCombo
                .HeaderText = "VAT Rate"
                .Name = .HeaderText
                Dim VATCol As New JCVATRateCollection

                VATCol.LoadAll(EntitySpaces.Interfaces.esSqlAccessType.StoredProcedure)
                For Each Rate As JCVATRate In VATCol
                    .Items.Add(Rate.str.VATRate)
                Next
                .Sorted = True

                VATCol = Nothing

                .ToolTipText = "Select VAT Rate"
                .AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
                .CellTemplate.Style.BackColor = Color.Honeydew
                .DisplayIndex = 8
                .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill

            End With
            .Columns.Add(VATCombo)
            VATCombo = Nothing

我希望能够为添加到网格的每个新行设置一个默认值,我还希望能够根据其他业务逻辑更改组合中的值。我意识到我可以直接设置单元格值,但我想避免将值硬编码到系统中并依赖数据库来填充。

我确定它一定是直截了当的,但它让我无法理解.....

【问题讨论】:

    标签: .net vb.net winforms datagridview


    【解决方案1】:

    EditGridView 中基本组合框的问题是所有行共享同一个组合框,所以你无法更改它。

    您要创建一个继承自 ComboBox 并实现 IDataGridViewEditingControl 的新类(ComboEditingControl):

    (例如 customdropdown.vb:)

    Imports System.Collections.Generic
    Imports System.Drawing
    Imports System.Windows.Forms
    
    Friend Class ComboEditingControl
    Inherits ComboBox
    Implements IDataGridViewEditingControl
    
    Private dataGridViewControl As DataGridView
    Private valueIsChanged As Boolean = False
    Private rowIndexNum As Integer
    Private ItemSelected As String
    
    Public Sub New()
        Me.DropDownStyle = ComboBoxStyle.DropDownList
    End Sub
    
    
    Public Property EditingControlFormattedValue() As Object _
        Implements IDataGridViewEditingControl.EditingControlFormattedValue
    
        Get
            Return ItemSelected
        End Get
    
        Set(ByVal value As Object)
            If TypeOf value Is Decimal Then
                Me.SelectedItem = value.ToString()
            End If
        End Set
    End Property
    
    
    Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) As Object _
        Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
        Return ItemSelected
    End Function
    
    Public ReadOnly Property EditingControlCursor() As Cursor _
        Implements IDataGridViewEditingControl.EditingPanelCursor
        Get
            Return MyBase.Cursor
        End Get
    End Property
    
    Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As DataGridViewCellStyle) _
        Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
    
        Me.Font = dataGridViewCellStyle.Font
        Me.ForeColor = dataGridViewCellStyle.ForeColor
        Me.BackColor = dataGridViewCellStyle.BackColor
    
    End Sub
    
    Public Property EditingControlRowIndex() As Integer _
        Implements IDataGridViewEditingControl.EditingControlRowIndex
    
        Get
            Return rowIndexNum
        End Get
        Set(ByVal value As Integer)
            rowIndexNum = value
        End Set
    
    End Property
    
    Public Function EditingControlWantsInputKey(ByVal key As Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean _
        Implements IDataGridViewEditingControl.EditingControlWantsInputKey
    
        ' Let the DateTimePicker handle the keys listed.
        Select Case key And Keys.KeyCode
            Case Keys.Up, Keys.Down, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp
                Return True
            Case Else
                Return False
        End Select
    End Function
    
    Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) _
        Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
        ' No preparation needs to be done.
    End Sub
    
    Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean Implements _
        IDataGridViewEditingControl.RepositionEditingControlOnValueChange
        Get
            Return False
        End Get
    End Property
    
    Public Property EditingControlDataGridView() As DataGridView _
        Implements IDataGridViewEditingControl.EditingControlDataGridView
    
        Get
            Return dataGridViewControl
        End Get
        Set(ByVal value As DataGridView)
            dataGridViewControl = value
        End Set
    
    End Property
    
    Public Property EditingControlValueChanged() As Boolean _
        Implements IDataGridViewEditingControl.EditingControlValueChanged
    
        Get
            Return valueIsChanged
        End Get
        Set(ByVal value As Boolean)
            valueIsChanged = value
        End Set
    End Property
    
    
    ''' <summary>
    ''' Notify the DataGridView that the contents of the cell have changed.
    ''' </summary>
    ''' <param name="eventargs"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub OnSelectedIndexChanged(ByVal eventargs As EventArgs)
        valueIsChanged = True
        dataGridViewControl.NotifyCurrentCellDirty(True)
        MyBase.OnSelectedItemChanged(eventargs)
        ItemSelected = SelectedItem.ToString()
    End Sub
    End Class
    

    另外 2 个类,请注意 InitializeEditingControl 您需要为您所在的特定行构建项目

    Friend Class ComboColumn
        Inherits DataGridViewColumn
    
        Public Sub New()
            MyBase.New(New ComboCell())
        End Sub
    
        Public Overrides Property CellTemplate() As DataGridViewCell
            Get
                Return MyBase.CellTemplate
            End Get
            Set(ByVal value As DataGridViewCell)
                ' Ensure that the cell used for the template is a ComboCell.
                If Not (value Is Nothing) AndAlso Not value.GetType().IsAssignableFrom(GetType(ComboCell)) Then
                    Throw New InvalidCastException("Must be a ComboCell")
                End If
                MyBase.CellTemplate = value
            End Set
        End Property
    End Class
    
    Friend Class ComboCell
        Inherits DataGridViewTextBoxCell
    
        Public Sub New()
        End Sub
    
        Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
            ' Set the value of the editing control to the current cell value.
            MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
    
            Dim ctl As ComboEditingControl = CType(DataGridView.EditingControl, ComboEditingControl)
    
            Dim GetValueFromRowToUseForBuildingCombo As String = Me.DataGridView.Rows(rowIndex).Cells(0).Value.ToString()
    
            ctl.Items.Clear()
            For Each thing As String In ACollection
                ctl.Items.Add(Sheet)
            Next
    
    
            If Me.Value Is Nothing Then
                ctl.SelectedIndex = -1
            Else
                ctl.SelectedItem = Me.Value
            End If
        End Sub
    
        Public Overrides ReadOnly Property EditType() As Type
            Get
                Return GetType(ComboEditingControl)
            End Get
        End Property
    
        Public Overrides ReadOnly Property ValueType() As Type
            Get
                Return GetType(String)
            End Get
        End Property
    
        Public Overrides ReadOnly Property FormattedValueType() As System.Type
            Get
                Return GetType(String)
            End Get
        End Property
    
        Public Overrides ReadOnly Property DefaultNewRowValue() As Object
            Get
                Return ""
            End Get
        End Property
    End Class
    

    最后在表单的 OnLoad 代码中,以编程方式将控件添加到 Grid:

    Dim c As New ComboColumn
    c.HeaderText = "Sheet"
    c.DataPropertyName = "My Combo"
    c.ToolTipText = "Select something from my combo"
    MyDataGridView.Columns.Add(c)
    

    要获取和设置,只需使用ThisRow.Cells(ComboCol).Value

    第一个字段是通用的,另一个继承并具有您需要的每个 DataGridView 的自定义代码

    HTH

    【讨论】:

    • 那么,一旦使用标准组合将列添加到网格视图中,您就不能访问项目集合吗?无论我尝试以哪种方式引用它,我都会得到一个字符串,尽管我实际上添加了一个具有两个属性(ID 和显示值)的对象。你还能如何处理主键?
    【解决方案2】:

    您不能使用行索引直接在单元格内转换控件以访问当前行吗?

    【讨论】:

      猜你喜欢
      • 2014-05-29
      • 2021-02-20
      • 2017-06-09
      • 2012-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多