将选中的行显示到另一个DataGridView中

时间:2016-05-09 10:40:52

标签: vb.net select datagridview datatable

我有一个DataGridView填充了DataTable 我添加了CheckBoxColumn来选择一些行。

我的目标是仅将选定的行显示在另一个DataGridView

我尝试使用Select完成此操作并将结果添加到新DataTable,但Select无法正常工作,因为CheckBoxColumn缺失。

以下是我用来填充第一个DataGridView并添加CheckBoxColumn的代码:

Dim chk0 As New DataGridViewCheckBoxColumn()
With chk0
    .AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
    .HeaderText = "Sel"
    .Name = "Sel"
End With
With Me.DataGridView1
    .Columns.Clear()
    .DataSource = DT_Events
    .Columns.Insert(0, chk0)
    .Columns("Event").AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
End With

然后,在检查了一些行后,我尝试将选定的行显示到另一行DataGridView

Using DT_Checked As DataTable = CType(Me.DataGridView1.DataSource, DataTable).Select("Sel = 1").CopyToDataTable
    If DT_Checked.Rows.Count > 0 Then
        With Me.DataGridView2
            .Visible = True
            .DataSource = DT_Checked
        End With
    Else
        MsgBox("No rows to show", MsgBoxStyle.Critical, "Error")
    End If
End Using

我在没有Select的情况下尝试了此代码,但它没有显示CheckBoxColumn
我该如何解决?
我怎么能这样做呢?

3 个答案:

答案 0 :(得分:1)

我建议您添加列" Sel"作为数据表中的Boolean" DT_Events" 。 将您的第一个代码更改为:

 DT_Events.Columns.Add("Sel", GetType(Boolean))
  DT_Events.Columns("Sel").SetOrdinal(0)
With Me.DataGridView1
    .Columns.Clear()
    .DataSource = DT_Events
    .Columns("Event").AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
End With

seconde代码可以将所选行复制到" DataGridView2"

答案 1 :(得分:1)

将行复制到新的DataTable是浪费的,因为两者之间唯一真正的区别是某些Boolean值是True还是False。由于您绑定到DataTable,因此您只需更改每个DGV中显示的视图。

标题中表达的概念 显示 选中的行... 复制不同> 行代码尝试执行的另一个控件。这将显示如何使用一个DataSource在每个DGV中显示一些行。

如果您的数据来自数据库,您可以在SQL中添加一列:

' Access version
Dim sql = "SELECT a, b, c, False AS Selected FROM SAMPLE"

这将为所有行添加一个初始化为False的布尔列,并将在DGV中显示为CheckBox

如果数据以其他方式进入DataTable ,请手动添加列:

dtSample.Columns.Add("Selected", GetType(Boolean))
dtSample.Columns("Selected").DefaultValue = False

' we need to loop and set a value
' if you manually add a column
For Each r As DataRow In dtSample.Rows
    r("Selected") = False
Next

要在一个网格(或列表框或组合)中显示行,或者根据该值显示另一个网格,此代码将使用2 DataViews。如果您正在使用视图,则通常需要随时更改RowFilter,因此请在表单中进行全局操作:

Private dtSample As DataTable          ' base table for BOTH DGVs
Private dvSource As DataView           ' ALL or Selected = False view
Private dvDest As DataView             ' Selected only
...
' build datatable and add the Selected Row (if needed)
...
' create Source DV as Selected = False
dvSource = New DataView(dtSample, "Selected=False", "", DataViewRowState.CurrentRows)

' create SELECTED DV as Selected = True
dvSelected = New DataView(dtSample, "Selected=True", "",DataViewRowState.CurrentRows)

dgv1.DataSource = dvSource
dgv2.DataSource = dvSelected 

dvSource是可选的。如果您希望在第一个DGV中显示所有行,那么DataView(根据问题似乎就是这种情况)。

为了便于说明,设置此项以便在DGV1中检查项目时它们会消失"从它(因为它们不再符合Selected = False标准),并自动出现在DGV2中(因为,现在他们符合该标准。结果:

enter image description here

在底部DGV中未选中/未选中的行将滑回到顶部。

经济实惠。您不仅无需运行任何代码来向第二个DGV添加或移动行,而且您不会创建 DataRows 的副本和新的{{1这样做。按DataTable(粗略但指示性),内存量与选定行的变化大致相同;手动复制它们时,当你制作包含相同相同数据的TaskManager副本时,它会慢慢爬上来。

答案 2 :(得分:0)

问题是数据表 DT_Events 没有 Sel 列,select选择网格的数据源,即您指定的数据表。

不是添加复选框列,而是在表 DT_Events 中添加布尔列 Sel 并分配给网格。