none
绑定DataGridView,使用DGV.DataBindings.Add()方法存在局限。虽然不常见,但还是贴出来吧。 RRS feed

  • 常规讨论

  • 我前两天问过绑定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会报错。但这不是问题的重点。

    大家都来说说。

    谢谢。







    2009年6月29日 18:10