0

我有一个使用 VB.NET 的 Windows 窗体应用程序,旨在升级 IIS Web 应用程序。

该应用程序有一个显示要升级的 Web 应用程序列表的 datagridview。其中一列是 DataGridViewComboBoxColumn。此组合框将其 DataSource 属性设置为数据表。我不为组合框使用绑定源。

这个想法是用户从 datagridview 行中的组合框中选择一个值,并更新同一 datagridview 行中的其他几个单元格的值。

EditingControlShowing 事件处理程序设置为设置组合框的 SelectedIndexChanged 事件。

Private Sub dgvWebApps_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles dgvWebApps.EditingControlShowing
    If dgvWebApps.CurrentCell.ColumnIndex = 5 Then
        Dim comboBox As ComboBox = CType(e.Control, ComboBox)
        If comboBox IsNot Nothing Then
            RemoveHandler comboBox.SelectedIndexChanged, AddressOf ComboBox_Value_Changed
            AddHandler comboBox.SelectedIndexChanged, AddressOf ComboBox_Value_Changed
            e.CellStyle.BackColor = clrLightYellow
        End If
    End If
End Sub

ComboBox_Value_Changed 是更新其他单元格值的子例程。

Private Sub ComboBox_Value_Changed(sender As Object, e As EventArgs)
    dgvWebApps.CurrentRow.Cells(frmMain.cnstNewVersion).Value = GetNewVersion(sender.Text)
    dgvWebApps.CurrentRow.Cells(frmMain.cnstSourcePath).Value = strSourcePath
    dgvWebApps.CurrentRow.Cells(frmMain.cnstSourceMediaFileUpdated).Value = True
    dgvWebApps.CurrentCell = dgvWebApps.CurrentRow.Cells(frmMain.cnstSourceMediaFile)
End Sub

当 datagridview 的 EditMode 属性设置为 EditOnEnter 时,还处理 datagridview 的 CurrentCellDirtyStateChanged 事件以立即提交当前编辑,并更新当前 datagridview 行中的单元格值。

Private Sub dgvWebApps_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles dgvWebApps.CurrentCellDirtyStateChanged
    If dgvWebApps.CurrentCell.ColumnIndex = 1 Then
        dgvWebApps.CurrentRow.Cells(frmMain.cnstLocalPath).Value = Path.Combine(strWebsitePhysicalPath, dgvWebApps.CurrentCell.Value)
    End If
    If dgvWebApps.IsCurrentCellDirty Then
        dgvWebApps.CommitEdit(DataGridViewDataErrorContexts.Commit)
    End If
End Sub

这通常工作正常。我可以从 datagridview 的组合框中选择不同的值,然后其他单元格相应地更新,同时移动到不同的单元格。

我遇到的问题是用户更改组合框的值,然后将表单上的焦点更改为 datagridview 以外的其他内容,然后单击返回到组合框之一。这是触发 datagridview 的 DataError 事件并且我得到一些相同的错误的时候。

这是错误:

错误消息: 设置 DataSource 属性时无法修改 Items 集合。

错误 StackTrace: 在 System.Windows.Forms.DataGridViewComboBoxCell.InitializeEditingControl 的 System.Windows.Forms.ComboBox.CheckNoDataSource() 处 System.Windows.Forms.DataGridView.InitializeEditingControlValue(DataGridViewCellStyle& dataGridViewCellStyle, DataGridViewCellStyle)数据网格视图单元)

该错误显然意味着在设置数据源属性时组合框的项目集合正在被修改。但是,代码中没有任何地方添加、删除或清除组合框的项目集合。

如果我继续处理所有错误,或者在数据网格的 DataError 事件期间没有弹出任何消息,那么一切似乎都按原样发生。我可以继续从组合框等中选择值。但是,如果我再次更改焦点并返回组合框,错误会再次发生。

据我所知,是在 ComboBox_Value_Changed 子例程期间其他单元格的值更改导致错误。删除这些会使错误消失。

现在,如果我使用 SelectionChangeCommitted 事件而不是 SelectedIndexChanged 事件让组合框调用 ComboBox_Value_Changed 子例程,也不会发生此错误。这是我最初使用的事件,但在表单上的某些用户交互中并没有始终如一地提出。这就是我在对这些行为进行一些研究后切换到 SelectedIndexChanged 事件的原因。

我不确定为什么在这些情况下会修改组合框的项目集合。如前所述,我可以只处理 datagridview 的 DataError 事件而不生成任何消息,并且一切似乎都按预期工作。如果可能的话,我只想知道这里发生了什么。如果我不需要,我不喜欢在错误发生时压制它们。

4

1 回答 1

0
于 2021-06-16T22:45:49.383 回答