VB.NET ComboBox控制DataGridView受控列值的修改

VB.NET ComboBox控制DataGridView受控列值的修改

说明事项:
  • 行选取模式不能选择 整行选取 SelectionMode = RowHeaderSelect
  • 可选设置 AllowUserToAddRows = False
  • 可选设置 ReadOnly = True
  • 如果 ComboBox 无法完美覆盖单元格,可以考虑修改DataGridView的行高,或ComboBox字号+1
  • 多个受控字段的情况:
    可以生成多个ComboBox对象,或Dictionary(Of String, ComboBox)对象。
    并在DataGridView1_CellMouseClickComboBox1_SelectionChangeCommitted事件中区分判断并赋值即可
  • 优点:
    不用每个受控列分别绑定DataGridViewComboBoxColumn列或DataGridViewComboBoxCell单元格对象, 减少了DataGridView对象刷新消耗;
    不受DataGridView数据和对象环境限制;
    响应速度不受数据量多少的影响。
  • 缺点:
    受控单元格依然显示的受控值Value,而非名称Key,对于使用者不太友好(报表打印会造成困扰);
    显示对象时,如果单元格大小、位置发生变化,会造成出现错位现象(需要代码做二次调整)。

分步说明
1. 创建ComboBox受控字典 填充测试数据
Private Sub Init_ComboBox()
    Dim dt As New DataTable
    With dt
        .Columns.Add("Key", GetType(String))
        .Columns.Add("Value", GetType(Integer))
        '测试数据
        .Rows.Add({"全世界", 0})
        .Rows.Add({"中国", 1})
        .Rows.Add({"美国", 2})
        .Rows.Add({"日本", 3})
        .Rows.Add({"苏格兰", 4})
        .Rows.Add({"斯洛伐克", 5})
        .Rows.Add({"埃及", 6})
    End With

    With ComboBox1
        .FlatStyle = FlatStyle.Popup
        .DropDownStyle = ComboBoxStyle.DropDownList
        .Items.Clear()
        .DataSource = dt
        .DisplayMember = "Key"
        .ValueMember = "Value"
    End With
End Sub
2. 初始化 DataGridView 填充测试数据
Private Sub Init_Dgv()
        With DataGridView1
            .Columns.Add("no", "序号")
            .Columns.Add("name", "姓名")
            .Columns.Add("age", "年龄")

            Dim rdm As New Random
            For i As Integer = 1 To 10
                .Rows.Add(i, "Harry", rdm.Next(0, 6))
            Next
        End With
    End Sub
3. 绘制 ComboBox 对象位置及大小(用户点击单元格事件)
Private Sub DataGridView1_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseClick
    Dim selectedColIndex = e.ColumnIndex

    '获取点击单元格在窗体中的位置和大小(Left、Top、Width、Height)
    Dim range As New System.Drawing.Rectangle
    range = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
    Dim dLeft = range.Left + DataGridView1.Left
    Dim dTop = range.Top + DataGridView1.Top

    '同步设置下拉框大小和位置
    ComboBox1.SetBounds(dLeft, dTop, range.Width, range.Height)
    '如果ComboBox和DataGridView在同一个容器内(Panel),可直接使用range对象的值
    'Cmb_CheckLevel.SetBounds(range.Left, range.Top, range.Width, range.Height)

    '根据原单元格值,设置初始ComboBox被选中索引
    ComboBox1.SelectedValue = DataGridView1.CurrentCell.Value
    ComboBox1.Show()
End Sub
4. 根据 ComboBox 变更项,修改当前单元格的值
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
    Dim cell As DataGridViewCell = DataGridView1.SelectedCells(0)  '获取当前单元格
    cell.Value = ComboBox1.SelectedValue    '单元格赋值
    DataGridView1.EndEdit()
    ComboBox1.Visible = False
End Sub

完整测试代码示例
Public Class Form1

#region "窗体初始化"
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Init_ComboBox()
        Init_Dgv()
    End Sub

    Private Sub Init_ComboBox()
        Dim items As New DataTable
        With items
            .Columns.Add("Key", GetType(String))
            .Columns.Add("Value", GetType(Integer))
            .Rows.Add({"全世界", 0})
            .Rows.Add({"中国", 1})
            .Rows.Add({"美国", 2})
            .Rows.Add({"日本", 3})
            .Rows.Add({"苏格兰", 4})
            .Rows.Add({"斯洛伐克", 5})
            .Rows.Add({"埃及", 6})
        End With

        With ComboBox1
            .FlatStyle = FlatStyle.Popup
            .DropDownStyle = ComboBoxStyle.DropDownList
            .Items.Clear()
            .DataSource = items
            .DisplayMember = "Key"
            .ValueMember = "Value"
        End With
    End Sub

    Private Sub Init_Dgv()
        With DataGridView1
            .Columns.Add("no", "序号")
            .Columns.Add("name", "姓名")
            .Columns.Add("age", "年龄")

            Dim rdm As New Random
            For i As Integer = 1 To 10
                .Rows.Add(i, "Harry", rdm.Next(0, 6))
            Next
        End With
    End Sub
#End Region

#Region "受控字段 编辑"
    Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) _
                Handles ComboBox1.SelectionChangeCommitted
        Dim cell As DataGridViewCell = DataGridView1.SelectedCells(0)
        cell.Value = ComboBox1.SelectedValue
        DataGridView1.EndEdit()
        ComboBox1.Visible = False
    End Sub

    Private Sub DataGridView1_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) _
                Handles DataGridView1.CellMouseClick
        Dim selectedColIndex = e.ColumnIndex

        '获取点击单元格在窗体中的位置和大小(Left、Top、Width、Height)
        Dim range As New System.Drawing.Rectangle
        range = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
        Dim dLeft = range.Left + DataGridView1.Left
        Dim dTop = range.Top + DataGridView1.Top

        '同步设置下拉框大小和位置
        ComboBox1.SetBounds(dLeft, dTop, range.Width, range.Height)

        '根据原单元格值,设置初始ComboBox被选中索引
        ComboBox1.SelectedValue = DataGridView1.CurrentCell.Value
        ComboBox1.Show()
    End Sub
#End Region

End Class

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值