.net - 将所选行从 DataGridView 复制到另一个,包括图像列

标签 .net vb.net image winforms datagridview

我目前正在尝试将选定的行从一个 DataGridView 复制到另一个。
我正在 try catch CheckBox 的值,如果它被选中,则整行将被复制到另一个 DataGridView。

例如,喜欢添加到购物车然后查看购物车。我引用了以下帖子:
Copy selected datagridrow to new datagridview on different form

不过好像没什么用。
我试过使用如下所示的 For 循环,但我不完全确定该怎么做。

Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
    Dim dt As New DataTable()
    AppendColumnsToDGV2()
    For Each row As DataGridViewRow In DataGridView1.Rows
        If row.Cells("SelectColumn").Value = True Then
            Dim NewRow As DataRow
            For i As Integer = 0 To row.Cells.Count - 1
                NewRow(i) = row.Cells(i).Value
                DataGridView2.Rows.Add(NewRow)
            Next
        End If
    Next

AppendColumnsToDGV2:

  Private Sub AppendColumnsToDGV2()
      Dim dt As New DataTable
      'dt.Columns.Add(CreateDGVCheckBoxCol())
      'dt.Columns.Add(CreateImageColumn())
      dt.Columns.Add(DataGridView1.Columns(3).HeaderText)
      dt.Columns.Add(DataGridView1.Columns(4).HeaderText)
      dt.Columns.Add(DataGridView1.Columns(5).HeaderText)
      dt.Columns.Add(DataGridView1.Columns(6).HeaderText)
      DataGridView2.DataSource = dt
End Sub

我在这里做的没有用,我不知道该怎么做。
任何帮助将不胜感激,谢谢。

每当我运行这段代码时,我都会收到错误:

System.NullReferenceException: Object reference not set to an instance of an object

我不确定如何修复它。

这是 DataGridView 的样子:

WhatDGVLooksLike

最佳答案

这个问题与上一个问题密切相关:
Display images in a DataGridView column using JSON objects as DataSource

您正在使用 Result 的子类 ( RootObject ) 填充第一个 DataGridView。

修改 Result 类如下:

  • 添加新属性, Selected As Boolean ,装饰有 <JsonIgnore> 属性。
  • 添加一个新的子类,名为 SelectionResult 在这里, Result 的一系列属性 您认为在第二个 DataGridView 中显示所选产品所需的类。
  • 添加复制方法Result 类返回自身的子部分作为 SelectionResult 对象。

Public Class Result
    <JsonIgnore>
    Public Property Selected As Boolean

    '(...)

    Public Function GetSelectionResult() As SelectionResult
        Return New SelectionResult With {
            .ID = Me.id,
            .Image = Me.Image,
            .Name = Me.Name,
            .ProductDescription = Me.ProductDescription,
            .Department = Me.Department,
            .Price = Me.Price,
            .Unitprice = Me.Unitprice
        }
    End Function
End Class

Public Class SelectionResult
    Public Property ID As Integer
    Public Property Image As Bitmap
    Public Property Name As String
    Public Property ProductDescription As String
    Public Property Department As String
    Public Property Price As Decimal
    Public Property Unitprice As Decimal
End Class
  • 添加两个 List(Of Class)作为表单中的字段。在上一个问题中,主类称为 ProductsQuery ,所以我重新使用已经在那里定义的名称:

Private CurrentProducts As List(Of ProductsQuery.Result) = New List(Of ProductsQuery.Result)()
Private SelectedProducts As List(Of ProductsQuery.SelectionResult) = New List(Of ProductsQuery.SelectionResult)()
  • 在填充第一个DataGridView的方法中,初始化 CurrentProducts 列表:

    CurrentProducts = New List(Of ProductsQuery.Result)()
    
  • JSON 反序列化后,用 JSON 结果填充列表:

    CurrentProducts.AddRange(JsonPost.uk.ghs.Products.Results)
    

在将所选产品添加到第二个 DataGridView 的 Button 的事件处理程序中,插入此代码:

编辑:
SelectedProducts列表保留在第一个 DataGridView 中选择的项目:只有 CurrentProducts 中没有的项目 列表被添加到选择中。

btnRemoveSelection 按钮从 SelectedProducts 中删除第二个 DataGridView 中的选定项列表。 DataGridView 的行选择有些麻烦,因此可能需要添加一个复选框列以简化要删除的项目的选择。

Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
    SelectedProducts.AddRange(CurrentProducts.
                       Where(Function(p) p.Selected = True AndAlso
                             (Not SelectedProducts.Any(Function(sp) sp.ID = p.id))).
                       Select(Function(p) p.GetSelectionResult()).ToArray())
    ResetCart()
End Sub

Private Sub btnRemoveSelection_Click(sender As Object, e As EventArgs) Handles btnRemoveSelection.Click
    If DataGridView2.SelectedRows.Count = 0 Then Return

    Dim itemsRemoved As Boolean = False
    Dim selectedItems() As Integer = DataGridView2.SelectedRows.
                                     OfType(Of DataGridViewRow)().
                                     Select(Function(r) CInt(r.Cells("ID").Value)).ToArray()
    For Each ID As Integer In selectedItems
        Dim currentIndex As Integer = SelectedProducts.FindIndex(Function(p) p.ID = ID)
        If currentIndex >= 0 Then
            SelectedProducts.RemoveAt(currentIndex)
            itemsRemoved = True
        End If
    Next
    If itemsRemoved Then
        ResetCart()
    End If
End Sub

Private Sub ResetCart()
    DataGridView2.DataSource = Nothing
    DataGridView2.DataSource = SelectedProducts
    DataGridView2.Columns(0).Visible = False
    DataGridView2.AutoResizeRows()
End Sub

这填充了 List(Of SelectedProducs) 使用第一个 DataGridView 的选定元素并将第二个 DataGridView 的数据源设置为此列表。

请注意,DataGridView 的第一列设置为 Visible = False ,因为该列对应于 ID 所选元素的属性

GetSelectionResult() Result 类返回已在 SelectionResult 中定义的属性值 类。您当然可以重新定义此类以包含您认为合适的任何属性。


这是这些修改的结果:

DataGridView JSON results

关于.net - 将所选行从 DataGridView 复制到另一个,包括图像列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54312447/

相关文章:

c# - Excel根据图像大小调整单元格大小

c# - 如何确定 Control.Visible 是通过属性设置的还是值是继承的

c# - 具有 Observable 的复杂流程

c# - NReco 错误 : "The specified executable is not a valid application for this OS platform"

vb.net - 检查空字节

c# - 如何创建没有 xmnls 属性的 XML 节点(例如 "image:image")? C#

c# - 插入日志事件时,TimeCreated 字段不够准确

mysql - 插入语句未使用正确的自动增量插入

javascript - 在 contenteditable div 中插入图像

css - 透明图像给出白色背景