Скопировать выбранные строки флажков из DGV в DGV2, включая столбец изображения - PullRequest
0 голосов
/ 22 января 2019

В настоящее время я пытаюсь скопировать выбранные строки из одного 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:

WhatDGVLooksLike

Ответы [ 3 ]

0 голосов
/ 22 января 2019

Если вы правильно связываете данные, ваши базовые данные будут обновляться при нажатии флажка.Тогда вы можете просто использовать LINQ.Вы должны избегать итерации по вашим DataGridViewRows всякий раз, когда это возможно (здесь это возможно), потому что они не должны хранить данные, а отображать их.

Этот простой пример работает в форме с двумя DataGridViews и одной кнопкой с именами по умолчанию, в vb.net.

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

enter image description here

0 голосов
/ 22 января 2019

Этот вопрос строго связан с предыдущим:
Отображение изображений в столбце DataGridView с использованием объектов JSON в качестве источника данных

Вы используете подкласс (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)
    

В обработчике события Button, который добавляет выбранные продукты во второй DataGridView, вставьте этот код:

Редактировать
Список SelectedProducts сохраняет элементы, выбранные в первом DataGridView: к элементу добавляются только элементы, которых еще нет в списке CurrentProducts.

Кнопка btnRemoveSelection удаляет выбранные элементы во втором DataGridView из списка SelectedProducts. Выбор строки DataGridView несколько громоздок, поэтому может потребоваться добавить столбец CheckBox, чтобы упростить выбор элементов для удаления.

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 и устанавливает DataSource второго DataGridView в этот список.

Обратите внимание, что для первого столбца объекта DataGridView установлено значение Visible = False, поскольку этот столбец соответствует свойству ID выбранного элемента

GetSelectionResult() класса Result возвращает значения свойств, которые были определены в классе SelectionResult. Конечно, вы можете переопределить этот класс, чтобы он содержал любые свойства, которые вы считаете подходящими.


Это результат следующих модификаций:

DataGridView JSON results

0 голосов
/ 22 января 2019

В настоящее время вы используете 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...