none
VS2010 VB.NET 设置单元格类型产生怪异现象 DataGridView setcurrentcelladdresscore 函数的可重入调用. RRS feed

  • 问题

  • VS2010 VB.NET 窗体中放置一个DataGridView,数据绑定到一个ACCESS2007数据库,我在CellEnter事件中添加如下代码:

    Private Sub DataGridView_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView.CellEnter
                Dim tmpCell As New DataGridViewComboBoxCell
                tmpCell.Items.AddRange({DataGridView.Item(e.ColumnIndex, e.RowIndex).Value, "OK"})
                DataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex) = tmpCell
              End Sub

    运行后:

    第1列的第一个单元格点击就发生<DataGridView setcurrentcelladdresscore 函数的可重入调用>错误,第2列的第二个单元格,第3列的第3个单元格......以此类推。

    不知道如何解决?



    • 已编辑 WZF_Work 2014年9月22日 13:30
    • 已移动 Caillen 2014年9月23日 3:04
    2014年9月22日 13:17

全部回复

  • EditingControlShowing 事件试试

    http://msdn.microsoft.com/zh-cn/library/system.windows.forms.datagridview.editingcontrolshowing%28v=vs.80%29.aspx


    http://feiyun0112.cnblogs.com/

    2014年9月23日 6:34
    版主
  • CellEnter事件触发之后,我们假设是第一个单元格(Index=0,Row=0),那么:

    1)以下两句话表示把该单元格内容添加到新的DataGridViewComboBoxCell中。

     Dim tmpCell As New DataGridViewComboBoxCell
     tmpCell.Items.AddRange({DataGridView.Item(e.ColumnIndex, e.RowIndex).Value, "OK"})

    2)以下一句话表示把刚创建的单元格赋值到当前单元格。

    DataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex) = tmpCell

    问题在于:当前单元格就是(0,0)那个,现在你把这个单元格添加到一个新的实体类中重新赋值给它?你究竟要干什么呢?


    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    2014年9月23日 7:52
    版主
  • 从你的代码来看,你是想给每一个comboboxcell添加一个“OK”选项,对吧?

    如果是这样的情况呢, 就算我们在cellclick 或者 用EditingControlShowing 事件 来设置items的集合,如果绑定的数据跟你的集合不匹配时依旧会碰到问题, 具体你可以尝试看下面的例子。

    Public Class Form1
        Dim dv As DataTable
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim dt As New DataTable
            With dt
                .Columns.Add("Column1")
                With .Rows
                    .Add("1")
                    .Add("2")
                    .Add("3")
                End With
            End With
            Dim cl1 As New DataGridViewComboBoxColumn
            With cl1
                .Items.AddRange({"1", "2", "3", "4"})
                .DataPropertyName = "Column1"
                .HeaderText = "Column1"
                .Name = "Column1"
            End With
            With DataGridView1
                .Columns.Add(cl1)
                .DataSource = dt
                .AllowUserToAddRows = False
                .AutoGenerateColumns = False
            End With
           
            dv = CType(DataGridView1.DataSource, DataTable).Copy()
        End Sub
    
        Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    
            Dim tmpCell As ComboBox = CType(e.Control, ComboBox)
            tmpCell.Items.Clear()
            tmpCell.Items.AddRange({dv.Rows(DataGridView1.CurrentCell.RowIndex)(DataGridView1.CurrentCell.ColumnIndex).ToString(), "OK"})
    
        End Sub
    End Class

    因此,建议你在绑定集合到这个column的时候添加这个“OK”选项。

    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim dt As New DataTable
            With dt
                .Columns.Add("Column1")
                With .Rows
                    .Add("1")
                    .Add("2")
                    .Add("3")
                End With
            End With
            Dim cl1 As New DataGridViewComboBoxColumn
            With cl1
                .Items.AddRange({"1", "2", "3", "4", "OK"})
                .DataPropertyName = "Column1"
                .HeaderText = "Column1"
                .Name = "Column1"
            End With
            With DataGridView1
                .Columns.Add(cl1)
                .DataSource = dt
                .AllowUserToAddRows = False
                .AutoGenerateColumns = False
            End With
        End Sub
    End Class


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    2014年9月28日 4:45
    版主
  • EditingControlShowing中e.Control是ReadOnly的,所以
    Dim tmpCell As ComboBox = CType(e.Control, ComboBox)会发生类型转换错误。
    2014年10月6日 2:44
  • EditingControlShowing中e.Control是ReadOnly的,所以
    Dim tmpCell As ComboBox = CType(e.Control, ComboBox)会发生类型转换错误。

    我试了下, 没碰到这问题……

    你确定是这个原因,会报这个错误?

    readonly, 类型转换会受影响? 比如下面这个例子

      Dim test As Object = CType(Me.OwnedForms, Object)

    OwnedForms 是readonly的  但是转换没有受影响……

    与其猜测这些问题

    不如告诉我们  你到底是想干什么呢


    remember make the reply as answer and vote the reply as helpful if it helps.

    2014年10月6日 3:02
  • 我的项目中是有一个DATAGRIDVIEW,绑定数据时每个单元格默认都是TEXTBOX,其中有几列,我想在获得焦点时,将单元格类型转化为COMBOBOX,并把单元格内容添加到COMBOBOX中,在失去焦点后,单元格再返回TEXTBOX类型。

    现在发生的奇怪问题是,当获得焦点的单元格的ROWINDEX和COLUMNSINDEX相等时,如(0,0:1,1:2,2.....)就会发生SETCURRENTCELLADDRESSCORE错误。

    2014年10月6日 4:45
  • 就像这个图片中的,其他单元格都正常,就是ROWINDEX和COLUMNSINDEX相等的单元格错误。
    2014年10月6日 4:52
  • 那为什么不用comboboxcolumn呢你可以设置它的

    .DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing

    平时显示的时候就是textbox的样子

        

    remember make the reply as answer and vote the reply as helpful if it helps.

    2014年10月6日 5:02
  • 因为实时转换相对灵活,我需要根据获得焦点的单元格内容添加不同的数据到COMBOBOX中,而且我的项目中有其他的表单列类型有CHECKEDBOX和COMBOBOX的。
    2014年10月6日 5:14
  • 因为实时转换相对灵活,我需要根据获得焦点的单元格内容添加不同的数据到COMBOBOX中,而且我的项目中有其他的表单列类型有CHECKEDBOX和COMBOBOX的。

    看起来你的代码会导致这个事件一直在触发进入死循环。

    既然是编辑的时候才需要, 那为什么不在CellBeginEdit事件中做这个处理呢?

     

    remember make the reply as answer and vote the reply as helpful if it helps.

    2014年10月6日 5:33
  • 我现在这样:

         

    Private Sub GridView_CellBeginEdit(sender As Object, e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles GridView.CellBeginEdit
        Dim tmpCell As New DataGridViewComboBoxCell

        tmpCell.Items.AddRange({DataGridView.Item(e.ColumnIndex, e.RowIndex).Value, "OK"})

        DataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex) = tmpCell

     

    End Sub

              

    Private Sub GridView_CellEndEdit(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles GridView.CellEndEdit
          Dim aa As New DataGridViewTextBoxCell
          GridView.Rows(e.RowIndex).Cells(e.ColumnIndex) = aa
     End Sub

    将转换放入CellBeginEdit和CellEndEdit事件中,错误不再发生了,但是当获得焦点的单元格的ROWINDEX和COLUMNSINDEX相等时,已经转化为COMBOBOX的单元格在CellEndEdit后无法转化为TEXTBOX,其他单元格完全正常。

    2014年10月6日 6:02
  • 简单总结下,其实你主要是想在编辑的时候显示下拉列表, 并且在完成编辑的时候不显示combobx的风格, 如果是这样的话,可以在cellbeginedit事件里设置下displaystyle。

    这样就不需要在cellendedit事件中做任何操作了。

      Private Sub DataGridView1_CellBeginEdit(sender As Object, e As DataGridViewCellCancelEventArgs) Handles DataGridView1.CellBeginEdit
            Dim tmpCell As New DataGridViewComboBoxCell
            tmpCell.Items.AddRange({DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value, "OK"})
            tmpCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing
            DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex) = tmpCell
        End Sub


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年10月9日 3:21
    版主