簡體   English   中英

將選定的行從 DataGridView 復制到另一個,包括圖像列

[英]Copy selected rows from a DataGridView to another, including Image Column

我目前正在嘗試將選定的行從一個 DataGridView 復制到另一個。
我試圖捕獲 CheckBox 的值,如果它被選中,那么整行將被復制到另一個 DataGridView。

例如,添加到購物車然后查看購物車。 我參考了以下帖子:
將選定的數據網格復制到不同表單上的新數據網格視圖

然而,它似乎沒有幫助。
我試過使用像下面這樣的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:未將對象引用設置為對象的實例

我不知道如何解決它。

這是 DataGridView 的樣子:

什么DGV看起來像

這個問題與上一個嚴格相關:
使用 JSON 對象作為數據源在 DataGridView 列中顯示圖像

您正在使用RootObject的子類 ( Result ) 來填充第一個 DataGridView。

修改Result類如下:

  • 添加一個新屬性Selected As Boolean ,用<JsonIgnore>屬性<JsonIgnore>
  • 添加一個新的子類,在此處稱為SelectionResult ,您認為在第二個 DataGridView 中需要選擇Result類的屬性來顯示所選產品。
  • 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 List:

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

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

在將所選產品添加到第二個 DataGridView 的 Button 的事件處理程序中,插入以下代碼:

編輯
SelectedProducts列表保留在第一個 DataGridView 中選擇的項目:僅將不在CurrentProducts列表中的項目添加到選擇中。

btnRemoveSelection Button 從SelectedProducts列表中刪除第二個 DataGridView 中的選定項。 DataGridView 行選擇有點麻煩,因此可能需要添加一個 CheckBox Column 以簡化要刪除的項目的選擇。

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

這將使用第一個 DataGridView 的選定元素填充List(Of SelectedProducs)並將第二個 DataGridView 的 DataSource 設置為此列表。

請注意,DataGridView 的第一 Column 設置為Visible = False ,因為該 Column 對應於所選元素的ID屬性

Result類的GetSelectionResult()返回在SelectionResult類中定義的屬性值。 您當然可以重新定義此類以包含您認為合適的任何屬性。


這是這些修改的結果:

DataGridView JSON 結果

如果數據綁定正確,則單擊復選框時,基礎數據將更新。 然后你可以只使用一些 LINQ。 您應該盡可能避免迭代 DataGridViewRows(這里是可能的),因為它們不應該保存數據,而是顯示它。

這個簡單的示例在 vb.net 中以具有兩個 DataGridView 和一個具有默認名稱的 Button 的形式工作。

Public Class Form1

    Private allProducts As List(Of Product)
    Private basketProducts As List(Of Product)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        allProducts = New List(Of Product) From {
                New Product() With {.Name = "Fairy Gel", .ID = 1},
                New Product() With {.Name = "Fairy Caps", .ID = 2},
                New Product() With {.Name = "Fairy Liquid", .ID = 3}}
        DataGridView1.DataSource = allProducts
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        basketProducts = allProducts.Where(Function(p) p.Selected).ToList()
        DataGridView2.DataSource = basketProducts
    End Sub

    ' dummy class to emulate your data
    Private Class Product
        Public Property Selected As Boolean
        Public Property Name As String
        Public Property ID As Long
    End Class

End Class

在此處輸入圖片說明

您當前正在使用 2 個單獨的數據表。 此外,您每次設置列值時都試圖添加行。 這可能對你有用。

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

Private Sub AppendColumnsToDGV2(dt As 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM