我前两天问过绑定DataGridView一共有几种方法。但是有出毛病的地方,所以很困惑。但是最终发现DataGridView.DataBindings.Add()方法有局限。用下面这个例子就可以显示这个问题。
Public Class Form1
Dim ds As New DataSet, dt As DataTable
Dim BoxItems() As String
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
InitializeComboBox1()
End Sub
Private Sub InitializeComboBox1()
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
ReDim BoxItems(1)
BoxItems(0) = "One"
BoxItems(1) = "Two"
ComboBox1.Items.AddRange(BoxItems)
End Sub
Private Sub InitializeDataGridView1()
dt = New DataTable("Test")
Dim Source As New BindingSource
Select Case ComboBox1.Text
Case "One"
With dt
.Columns.Add("1", GetType(String))
.Columns.Add("2", GetType(String))
End With
ds.Tables.Add(dt)
Source.DataSource = ds
Dim CountColumn As Integer
With Dialog1.DataGridView1
.DataBindings.Add("DataSource", Source, "Test")
''.DataSource = Source
''.DataMember = "Test"
For CountColumn = 0 To dt.Columns.Count - 1
.Columns(CountColumn).SortMode = DataGridViewColumnSortMode.NotSortable
Next
End With
Case "Two"
'Nothing here.
End Select
End Sub
Private Sub ComboBox1_DropDownClosed(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.DropDownClosed
InitializeDataGridView1()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dialog1.ShowDialog()
End Sub
End Class
实现这个例子,你需要:Form1和Dialog1。其中,Form1上有如下控件:ComboBox1,DataGridView1,和Button1。在Dialog1上有DataGridView1。
运行程序,在循环部分就会有提示,说Index超出范围。
但是如果把
.DataBindings.Add("DataSource", Source, "Test")这句,注释掉,启用被原先注释掉的定义DataSource,DataMember的两句。程序运行正常。
如果不注释掉
.DataBindings.Add("DataSource", Source, "Test")这句,而删除With Dialog1.DataGridView1这句中的Dialog1.,程序也能正常运行,只是这次是显示在Form1的DataGridView1中。
我把代码放到Module中还是一样。但是如果把Private Sub InitializeDataGridView1()放到Dialog1中就没有问题(变量声明也要改)。
其实用DataSource和ControlBindingsCollection.Add方法都是干了同一个事情:指定DataSource和DataMember。我之所以会认为这是问题是因为,用DataSource方法绑定数据不论是Form1还是Dialog1都不出问题。而DataGridView.DataBindings.Add()出现了不能在其他窗体上正确绑定DataGridView的情况。
对这个问题唯一我能想到的解释是,ControlBindingsCollection.Add用于简单数据绑定,并不太完善。也就是说,它干这个活儿勉强了。但它又能在同一个窗体中完成对DataGridView的数据绑定。所以看上去像是BUG。(个人认为是BUG)。
我程序写的不规范(在Form1中操作Dialog1上的控件(这样算不算不好?)),也可能是问题所在。但是不规范的写法DataSource能用,而ControlBindingsCollection.Add就不行。还是说ControlBindingsCollection.Add有这样的限制?
还有我没加判断所以连续调用Dialog1会报错。但这不是问题的重点。
大家都来说说。
谢谢。