将新记录粘贴到绑定的 DataGridView
Pasting new records to a Bound DataGridView
如果有人问过这个问题,我们深表歉意。如果是这样,我无法找到一个简单的解决方案。我试图允许用户在 DataGridView 中 copy/paste 多条记录(数据的内存副本,稍后当用户单击保存按钮时保存)并且找不到任何有效的东西。这可能是因为我对这一切有些不理解。
我使用 Visual Studio 的 drag/table 将标准编辑表单设置为一个表单,因此它使用了 BindingSource 控件和所有其他随之而来的控件。当手动在新行中逐条输入内容时,它工作得很好,因此它似乎设置正确,但是当涉及到使用代码添加记录(或多条记录)时,似乎没有任何效果。
我尝试了下面代码中概述的一些事情。有人可以至少引导我朝着正确的方向前进吗?粘贴多条记录不会那么难。
我 运行 当用户按下 Control-V 时(剪贴板正确保存分隔字符串):
Private Sub PasteClipboard()
If Clipboard.ContainsText Then
Dim sLines() As String = Clipboard.GetText.Split(vbCrLf)
For Each sLine As String In sLines
Dim Items() As String = sLine.Split(vbTab)
Dim drv As DataRowView = AdjustmentsBindingSource.AddNew()
drv.Item(1) = Items(0)
drv.Item(2) = Items(1)
drv.Item(3) = Items(2)
drv.Item(4) = Items(3)
'Error on next line : Cannot add external objects to this list.
AdjustmentsBindingSource.Add(drv)
Next
End If
End Sub
编辑
(bindingsource绑定了一个dataadapter,它绑定了一个mdb文件中的table,如果这样有助于理解的话)
我将代码的内部部分调整为:
If (RowHasData(Items)) Then
Dim drv As DataRowView = AdjustmentsBindingSource.AddNew()
drv.Item("FontName") = Items(0)
drv.Item("FontSize") = Items(1)
drv.Item("LetterCombo") = Items(2)
drv.Item("Adjustment") = Items(3)
drv.Item("HorV") = Items(4)
End If
它有点管用,但它还在 2 个新行之前添加了一个空白行。不确定这是从哪里来的,因为我什至包括了你的 RowHasData()
例程...
我认为“attemp3”应该有效,但是,尚不清楚 AdjustmentsBindingSource’s
DataSource
是“什么”。是 List<T>
还是 DataTable
?
如果我将 BinngSource.DataSource
设置为 DataTable
,则尝试 3 似乎有效。下面是一个有效的例子。
Private Sub PasteClipboard2()
If Clipboard.ContainsText Then
Dim sLines() As String = Clipboard.GetText.Split(vbCrLf)
For Each sLine As String In sLines
Dim Items() As String = sLine.Split(vbTab)
If (RowHasData(Items)) Then
Dim drv As DataRowView = AdjustmentsBindingSource.AddNew()
drv.Item("FontName") = Items(0)
drv.Item("FontSize") = Items(1)
drv.Item("LetterCombo") = Items(2)
drv.Item("Adjustment") = Items(3)
drv.Item("HorV") = Items(4)
End If
Next
End If
End Sub
这似乎在我的测试中有效。我添加了一个小函数 (RowHasData) 来避免格式错误的字符串导致问题。它只是检查大小(至少 5 个项目)并检查以确保一行实际上有“一些”数据。如果某行只是空字符串,则会被忽略。
Private Function RowHasData(items As String())
If (items.Count >= 5) Then
For Each item In items
If (item <> "") Then Return True
Next
End If
Return False
End Function
我猜想将新行“直接”添加到 BindingSource
的 DataSource.
中同样容易 在下面的示例中,代码是“直接”添加行到用作 DataSource
的 DataTable
到 BindingSource.
我相信您可以通过简单地向列表添加一个新对象来对 List<T>
做同样的事情。下面是一个使用 BindingSource
和 DataTable
的完整示例。这只是将行添加到 table.
的底部
Dim gridTable1 As DataTable
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PasteClipboard()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
gridTable1 = GetTable()
FillTable(gridTable1)
AdjustmentsBindingSource.DataSource = gridTable1
AdjustmentsDataGridView.DataSource = AdjustmentsBindingSource
End Sub
Private Function GetTable() As DataTable
Dim dt = New DataTable()
dt.Columns.Add("FontName", GetType(String))
dt.Columns.Add("FontSize", GetType(String))
dt.Columns.Add("LetterCombo", GetType(String))
dt.Columns.Add("Adjustment", GetType(String))
dt.Columns.Add("HorV", GetType(String))
Return dt
End Function
Private Sub FillTable(dt As DataTable)
For index = 1 To 10
dt.Rows.Add("Name_" + index.ToString(), "Size_" + index.ToString(), "Combo_" + index.ToString(), "Adjust_" + index.ToString(), "HorV_" + index.ToString())
Next
End Sub
Private Sub PasteClipboard()
If Clipboard.ContainsText Then
Dim sLines() As String = Clipboard.GetText.Split(vbCrLf)
Try
Dim dataRow As DataRow
For Each sLine As String In sLines
Dim Items() As String = sLine.Split(vbTab)
If (RowHasData(Items)) Then
dataRow = gridTable1.NewRow()
dataRow("FontName") = Items(0)
dataRow("FontSize") = Items(1)
dataRow("LetterCombo") = Items(2)
dataRow("Adjustment") = Items(3)
dataRow("HorV") = Items(4)
gridTable1.Rows.Add(dataRow)
End If
Next
Catch ex As Exception
MessageBox.Show("Error: " + ex.Message)
End Try
End If
End Sub
Private Function RowHasData(items As String())
If (items.Count >= 5) Then
For Each item In items
If (item <> "") Then Return True
Next
End If
Return False
End Function
希望代码对您有所帮助...
最后但重要的是,我只是猜测您可能没有“测试”用户可以“SELECT”数据的不同方式以及其他应用程序“如何”“复制”selected数据。我以前使用 WIN-OS“剪贴板”进行的测试有时会产生意想不到的结果。例如,如果用户 select 的多个项目使用“Ctrl”键“添加”到 selection,如果 selection 不连续,剪贴板中会出现额外的行。我的重点是使用 OS 剪贴板是古怪的恕我直言。我建议对用户可以 select 数据的“不同”方式进行大量测试。如果这不是问题,那么上面的代码应该可以工作。
如果有人问过这个问题,我们深表歉意。如果是这样,我无法找到一个简单的解决方案。我试图允许用户在 DataGridView 中 copy/paste 多条记录(数据的内存副本,稍后当用户单击保存按钮时保存)并且找不到任何有效的东西。这可能是因为我对这一切有些不理解。
我使用 Visual Studio 的 drag/table 将标准编辑表单设置为一个表单,因此它使用了 BindingSource 控件和所有其他随之而来的控件。当手动在新行中逐条输入内容时,它工作得很好,因此它似乎设置正确,但是当涉及到使用代码添加记录(或多条记录)时,似乎没有任何效果。
我尝试了下面代码中概述的一些事情。有人可以至少引导我朝着正确的方向前进吗?粘贴多条记录不会那么难。
我 运行 当用户按下 Control-V 时(剪贴板正确保存分隔字符串):
Private Sub PasteClipboard()
If Clipboard.ContainsText Then
Dim sLines() As String = Clipboard.GetText.Split(vbCrLf)
For Each sLine As String In sLines
Dim Items() As String = sLine.Split(vbTab)
Dim drv As DataRowView = AdjustmentsBindingSource.AddNew()
drv.Item(1) = Items(0)
drv.Item(2) = Items(1)
drv.Item(3) = Items(2)
drv.Item(4) = Items(3)
'Error on next line : Cannot add external objects to this list.
AdjustmentsBindingSource.Add(drv)
Next
End If
End Sub
编辑
(bindingsource绑定了一个dataadapter,它绑定了一个mdb文件中的table,如果这样有助于理解的话)
我将代码的内部部分调整为:
If (RowHasData(Items)) Then
Dim drv As DataRowView = AdjustmentsBindingSource.AddNew()
drv.Item("FontName") = Items(0)
drv.Item("FontSize") = Items(1)
drv.Item("LetterCombo") = Items(2)
drv.Item("Adjustment") = Items(3)
drv.Item("HorV") = Items(4)
End If
它有点管用,但它还在 2 个新行之前添加了一个空白行。不确定这是从哪里来的,因为我什至包括了你的 RowHasData()
例程...
我认为“attemp3”应该有效,但是,尚不清楚 AdjustmentsBindingSource’s
DataSource
是“什么”。是 List<T>
还是 DataTable
?
如果我将 BinngSource.DataSource
设置为 DataTable
,则尝试 3 似乎有效。下面是一个有效的例子。
Private Sub PasteClipboard2()
If Clipboard.ContainsText Then
Dim sLines() As String = Clipboard.GetText.Split(vbCrLf)
For Each sLine As String In sLines
Dim Items() As String = sLine.Split(vbTab)
If (RowHasData(Items)) Then
Dim drv As DataRowView = AdjustmentsBindingSource.AddNew()
drv.Item("FontName") = Items(0)
drv.Item("FontSize") = Items(1)
drv.Item("LetterCombo") = Items(2)
drv.Item("Adjustment") = Items(3)
drv.Item("HorV") = Items(4)
End If
Next
End If
End Sub
这似乎在我的测试中有效。我添加了一个小函数 (RowHasData) 来避免格式错误的字符串导致问题。它只是检查大小(至少 5 个项目)并检查以确保一行实际上有“一些”数据。如果某行只是空字符串,则会被忽略。
Private Function RowHasData(items As String())
If (items.Count >= 5) Then
For Each item In items
If (item <> "") Then Return True
Next
End If
Return False
End Function
我猜想将新行“直接”添加到 BindingSource
的 DataSource.
中同样容易 在下面的示例中,代码是“直接”添加行到用作 DataSource
的 DataTable
到 BindingSource.
我相信您可以通过简单地向列表添加一个新对象来对 List<T>
做同样的事情。下面是一个使用 BindingSource
和 DataTable
的完整示例。这只是将行添加到 table.
Dim gridTable1 As DataTable
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PasteClipboard()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
gridTable1 = GetTable()
FillTable(gridTable1)
AdjustmentsBindingSource.DataSource = gridTable1
AdjustmentsDataGridView.DataSource = AdjustmentsBindingSource
End Sub
Private Function GetTable() As DataTable
Dim dt = New DataTable()
dt.Columns.Add("FontName", GetType(String))
dt.Columns.Add("FontSize", GetType(String))
dt.Columns.Add("LetterCombo", GetType(String))
dt.Columns.Add("Adjustment", GetType(String))
dt.Columns.Add("HorV", GetType(String))
Return dt
End Function
Private Sub FillTable(dt As DataTable)
For index = 1 To 10
dt.Rows.Add("Name_" + index.ToString(), "Size_" + index.ToString(), "Combo_" + index.ToString(), "Adjust_" + index.ToString(), "HorV_" + index.ToString())
Next
End Sub
Private Sub PasteClipboard()
If Clipboard.ContainsText Then
Dim sLines() As String = Clipboard.GetText.Split(vbCrLf)
Try
Dim dataRow As DataRow
For Each sLine As String In sLines
Dim Items() As String = sLine.Split(vbTab)
If (RowHasData(Items)) Then
dataRow = gridTable1.NewRow()
dataRow("FontName") = Items(0)
dataRow("FontSize") = Items(1)
dataRow("LetterCombo") = Items(2)
dataRow("Adjustment") = Items(3)
dataRow("HorV") = Items(4)
gridTable1.Rows.Add(dataRow)
End If
Next
Catch ex As Exception
MessageBox.Show("Error: " + ex.Message)
End Try
End If
End Sub
Private Function RowHasData(items As String())
If (items.Count >= 5) Then
For Each item In items
If (item <> "") Then Return True
Next
End If
Return False
End Function
希望代码对您有所帮助...
最后但重要的是,我只是猜测您可能没有“测试”用户可以“SELECT”数据的不同方式以及其他应用程序“如何”“复制”selected数据。我以前使用 WIN-OS“剪贴板”进行的测试有时会产生意想不到的结果。例如,如果用户 select 的多个项目使用“Ctrl”键“添加”到 selection,如果 selection 不连续,剪贴板中会出现额外的行。我的重点是使用 OS 剪贴板是古怪的恕我直言。我建议对用户可以 select 数据的“不同”方式进行大量测试。如果这不是问题,那么上面的代码应该可以工作。