homesite 发表于 2007-11-1 13:27

用Vb.net 2005郁闷死了!

<P>问题1: DataGridView的AllowUserToAddRows=True时,如果把光标移入其最后的新行(空白行)后(没有输入任何内容,此时也DataGridView也没有自动增加一新行),如果再执行Me.sqlAdapter.Update(sqlDataSource.DataSource)则出错,说是无法将NUll值插入某某列(该列确实不能为空),问题是前段时间我都是用同样的方法做了十几个这功能的窗口调试时都没有没错,今天一运行就出现这样的错误,问题何在?<BR></P>
<P>问题2:Try<BR>           Me.sqlAdapter.Update(sqlDataSource.DataSource)<BR>        Catch ex As Exception<BR>           MsgBox(ex.Message, MsgBoxStyle.Exclamation, "错误")<BR>        End Try<BR>当有错时 MsgBox(ex.Message, MsgBoxStyle.Exclamation, "错误")的提示信息一闪而过(前段时间都不会),我原来用Vb.net 2003设计ASP.net程序时开始设计阶段不会,后来也有这样的问题,问题何在?<BR></P>
<P>问题1和问题2都是今天才发生的!<BR></P>

qlong0728 发表于 2007-11-1 15:02

编程思路不够清晰,代码不够精密,构思不够成熟[em27]

homesite 发表于 2007-11-1 15:46

?

homesite 发表于 2007-11-1 16:28

<P><br>以下是代码,帮我看看,谢谢!<br></P>
<P>另,该窗口如果做为子窗口在父窗口里运行,还有个问题,请参见我之前提的“程序为什么会没有响应?”</P>
<P>Public Class frmDefineBank<br>    Dim blnLoadForm As Boolean<br>    Dim sqlConn As SqlConnection<br>    Dim sqlCommand As SqlCommand<br>    Dim sqlAdapter As SqlDataAdapter<br>    Dim sqlDataSet As New DataSet<br>    Dim sqlDataSource As New BindingSource<br>    Dim blnContextChanged, blnRowValidated As Boolean<br>    Dim commandBuilder As SqlCommandBuilder</P>
<P>    '退出窗体时提示是否保存<br>    Private Sub frmDefineBank_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing<br>        If blnContextChanged Then<br>            If Not blnRowValidated Then<br>                e.Cancel = True<br>            Else<br>                Select Case publicfunIsSaveOrCancel()<br>                    Case MsgBoxResult.Yes<br>                        Try<br>                            Me.sqlAdapter.Update(sqlDataSource.DataSource)<br>                        Catch ex As Exception<br>                            MsgBox(ex.Message, MsgBoxStyle.Exclamation, "错误")<br>                        End Try<br>                    Case MsgBoxResult.Cancel<br>                        e.Cancel = True<br>                        Exit Sub<br>                End Select<br>            End If<br>        End If<br>    End Sub</P>
<P>    '按ESC键关闭窗口<br>    Private Sub frmDefineBank_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown<br>        If e.KeyValue = 27 Then<br>            If blnContextChanged Then<br>                If Not blnRowValidated Then<br>                    Exit Sub<br>                Else<br>                    Select Case publicfunIsSaveOrCancel()<br>                        Case MsgBoxResult.Yes<br>                            Try<br>                                Me.sqlAdapter.Update(sqlDataSource.DataSource)<br>                            Catch ex As Exception<br>                                MsgBox(ex.Message, MsgBoxStyle.Exclamation, "错误")<br>                            End Try<br>                        Case MsgBoxResult.Cancel<br>                            Exit Sub<br>                    End Select<br>                End If<br>            End If<br>            blnContextChanged = False<br>            Me.Close()<br>        End If<br>    End Sub</P>
<P>    Private Sub frmDefineBank_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load<br>        blnLoadForm = True<br>        blnRowValidated = True<br>        Try<br>            sqlConn = New SqlConnection(sqlConString)<br>            sqlCommand = New SqlCommand("Select bankNumber,bankName,bankAccount,bankMaster  From DEBK", sqlConn)<br>            sqlAdapter = New SqlDataAdapter(sqlCommand)<br>            commandBuilder = New SqlCommandBuilder(sqlAdapter)<br>            sqlAdapter.Fill(sqlDataSet, "DEBK")<br>            '将DataGridView控件邦定到指定的数据表中<br>            sqlDataSource.DataSource = sqlDataSet.Tables("DEBK")<br>            Me.DataGridView1.DataSource = sqlDataSource<br>            Dim columnBankNumber As New DataGridViewTextBoxColumn<br>            Dim columnBankName As New DataGridViewTextBoxColumn<br>            Dim columnBankAccount As New DataGridViewTextBoxColumn<br>            Dim columnBankMaster As New DataGridViewTextBoxColumn</P>
<P>            With columnBankNumber<br>                .Name = "银行编号"<br>                .MaxInputLength = 8<br>                .DataPropertyName = "bankNumber"<br>                .SortMode = DataGridViewColumnSortMode.NotSortable<br>            End With</P>
<P>            With columnBankName<br>                .Name = "开户行"<br>                .MaxInputLength = 50<br>                .DataPropertyName = "bankName"<br>                .SortMode = DataGridViewColumnSortMode.NotSortable<br>            End With</P>
<P>            With columnBankAccount<br>                .Name = "帐号"<br>                .MaxInputLength = 50<br>                .DataPropertyName = "bankAccount"<br>                .SortMode = DataGridViewColumnSortMode.NotSortable<br>            End With</P>
<P>            With columnBankMaster<br>                .Name = "开户方"<br>                .MaxInputLength = 50<br>                .DataPropertyName = "bankMaster"<br>                .SortMode = DataGridViewColumnSortMode.NotSortable<br>            End With</P>
<P>            Me.DataGridView1.Columns("bankNumber").Visible = False<br>            Me.DataGridView1.Columns("bankName").Visible = False<br>            Me.DataGridView1.Columns("bankAccount").Visible = False<br>            Me.DataGridView1.Columns("bankMaster").Visible = False<br>            Me.DataGridView1.Columns.Add(columnBankNumber)<br>            Me.DataGridView1.Columns.Add(columnBankName)<br>            Me.DataGridView1.Columns.Add(columnBankAccount)<br>            Me.DataGridView1.Columns.Add(columnBankMaster)<br>            Me.DataGridView1.Columns("银行编号").MinimumWidth = 80<br>            Me.DataGridView1.Columns("开户行").MinimumWidth = 130<br>            Me.DataGridView1.Columns("帐号").MinimumWidth = 130<br>            Me.DataGridView1.Columns("开户方").MinimumWidth = 130<br>            Me.DataGridView1.Columns("银行编号").Width = 80<br>            Me.DataGridView1.Columns("开户行").Width = 130<br>            Me.DataGridView1.Columns("帐号").Width = 130<br>            Me.DataGridView1.Columns("开户方").Width = 130<br>            Me.DataGridView1.Columns("开户方").AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells<br>        Catch ex As Exception<br>            MsgBox(ex.Message, MsgBoxStyle.Exclamation, "错误")<br>        End Try<br>        blnLoadForm = False<br>    End Sub</P>
<P>    '验证一行的“银行编号”、“开户行”、“帐号”是否为空<br>    Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating<br>        If blnLoadForm Then Exit Sub '加载窗体中跳过行验证<br>        If e.RowIndex = Me.DataGridView1.Rows.Count - 1 Then Exit Sub<br>        If String.IsNullOrEmpty(Me.DataGridView1.Rows(e.RowIndex).Cells("银行编号").Value.ToString.Trim) Then<br>            Me.DataGridView1.Rows(e.RowIndex).Cells("银行编号").Selected = True<br>            Me.DataGridView1.BeginEdit(True)<br>            Me.DataGridView1.Rows(e.RowIndex).ErrorText = "银行编号不能为空"<br>            blnRowValidated = False<br>            e.Cancel = True<br>            Exit Sub<br>        End If<br>        If String.IsNullOrEmpty(Me.DataGridView1.Rows(e.RowIndex).Cells("开户行").Value.ToString.Trim) Then<br>            Me.DataGridView1.Rows(e.RowIndex).Cells("开户行").Selected = True<br>            Me.DataGridView1.BeginEdit(True)<br>            Me.DataGridView1.Rows(e.RowIndex).ErrorText = "开户行不能为空"<br>            blnRowValidated = False<br>            e.Cancel = True<br>            Exit Sub<br>        End If<br>        If String.IsNullOrEmpty(Me.DataGridView1.Rows(e.RowIndex).Cells("帐号").Value.ToString.Trim) Then<br>            Me.DataGridView1.Rows(e.RowIndex).Cells("帐号").Selected = True<br>            Me.DataGridView1.BeginEdit(True)<br>            Me.DataGridView1.Rows(e.RowIndex).ErrorText = "帐号不能为空"<br>            blnRowValidated = False<br>            e.Cancel = True<br>            Exit Sub<br>        End If<br>        blnRowValidated = True<br>    End Sub</P>
<P>    '验证单元格是否为空,并验证“银行编号”是否唯一<br>    Private Sub DataGridView1_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating<br>        If e.RowIndex = Me.DataGridView1.Rows.Count - 1 Then Exit Sub<br>        Select Case e.ColumnIndex<br>            Case 4<br>                If String.IsNullOrEmpty(e.FormattedValue.ToString.Trim) Then<br>                    Me.DataGridView1.Rows(e.RowIndex).ErrorText = "银行编号不能为空"<br>                    e.Cancel = True<br>                Else<br>                    Dim i As Integer<br>                    For i = 0 To Me.DataGridView1.Rows.Count - 2<br>                        If e.RowIndex = i Then Continue For<br>                        If Me.DataGridView1.Rows(i).Cells("银行编号").Value.ToString.ToUpper.Trim = e.FormattedValue.ToString.ToUpper.Trim Then<br>                            Me.DataGridView1.Rows(e.RowIndex).ErrorText = "银行编号已定义"<br>                            e.Cancel = True<br>                            Exit Sub<br>                        End If<br>                    Next<br>                End If<br>            Case 5<br>                If String.IsNullOrEmpty(e.FormattedValue.ToString.Trim) Then<br>                    Me.DataGridView1.Rows(e.RowIndex).ErrorText = "开户行不能为空"<br>                    e.Cancel = True<br>                End If<br>            Case 6<br>                If String.IsNullOrEmpty(e.FormattedValue.ToString.Trim) Then<br>                    Me.DataGridView1.Rows(e.RowIndex).ErrorText = "帐号不能为空"<br>                    e.Cancel = True<br>                End If<br>        End Select<br>    End Sub</P>
<P>    '单元格内容更改时标记“已更改“<br>    Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged<br>        ' blnContextChanged是用来记录内容的更改;<br>        '加载窗体中跳过<br>        If blnLoadForm Then Exit Sub<br>        blnContextChanged = True<br>    End Sub</P>
<P>    '单元格退出编辑模式时<br>    Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit<br>        '截掉单元格内容的左右空格字符<br>        If e.RowIndex = Me.DataGridView1.Rows.Count - 1 Then Exit Sub<br>        Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString.Trim<br>        Me.DataGridView1.Rows(e.RowIndex).ErrorText = Nothing<br>    End Sub</P>
<P>    '确定按钮事件<br>    Private Sub btnConfirm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConfirm.Click<br>        If Not blnRowValidated Then Exit Sub<br>        If blnContextChanged Then<br>            Try<br>                Me.sqlAdapter.Update(sqlDataSource.DataSource)<br>            Catch ex As Exception<br>                MsgBox(ex.Message, MsgBoxStyle.Exclamation, "错误")<br>            End Try<br>        End If<br>        blnContextChanged = False<br>        Me.Close()<br>    End Sub</P>
<P>    '关闭按钮事件<br>    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click<br>        If Not blnRowValidated Then Exit Sub<br>        If blnContextChanged Then<br>            If publicFunIsSave() Then<br>                Try<br>                    Me.sqlAdapter.Update(sqlDataSource.DataSource)<br>                Catch ex As Exception<br>                    MsgBox(ex.Message, MsgBoxStyle.Exclamation, "错误")<br>                End Try<br>            End If<br>        End If<br>        blnContextChanged = False<br>        Me.Close()<br>    End Sub<br>End Class</P>
[align=right][color=#000066][此贴子已经被作者于2007-11-1 16:32:38编辑过][/color][/align]

qlong0728 发表于 2007-11-2 08:28

Dim sqlConn As SqlConnection<BR>应改为<BR>Dim sqlConn As New SqlClient.SqlConnection<BR><BR><BR>sqlConn = New SqlConnection(sqlConString)<BR>sqlCommand = New SqlCommand("Select bankNumber,bankName,bankAccount,bankMaster  From DEBK", sqlConn)<BR>sqlAdapter = New SqlDataAdapter(sqlCommand)<BR>commandBuilder = New SqlCommandBuilder(sqlAdapter)<BR>sqlAdapter.Fill(sqlDataSet, "DEBK")<BR>这段如是换成我写,我会这样写<BR>Dim daaaa As New SqlClient.SqlDataAdapter<BR>SQLtile = "Select bankNumber,bankName,bankAccount,bankMaster  From DEBK"<BR>daaaa.SelectCommand = New SqlClient.SqlCommand(SQLtile, sqlConn)<BR>daaaa.Fill(sqlDataSet)<BR>DataGridView1.DataSource = sqlDataSet.Tables(0)<BR>其它的自己慢慢检查一下,在定义时,有些是需要加AS NEW的或加上AS NEW SqlClient的<BR><BR>只供参考....

homesite 发表于 2007-11-2 09:26

<P>谢谢您的建议!<br><br>之所以没这样写:<br>SQLtile = "Select bankNumber,bankName,bankAccount,bankMaster  From DEBK"<br>daaaa.SelectCommand = New SqlClient.SqlCommand(SQLtile, sqlConn)<br>因为觉得命令字符串不是太长并不影响编写和查看的话没必要定义一个变量来存储(命令比较长的话我也是采用这样的方法的),定义一个变量来存储不是要消耗内存资源的吗?(虽然消耗得不多,但是能节约就节约)<br></P>
<P>另外,有的申明要用NEW关键字这是肯定的了,没用的话程序就不会执行了,之所以省略了sqlClient那是因为我在项目里已经导入了System.Data.SqlClient命名空间了.<br></P>
<P>这些暂且不说,我只想知道我提的问题怎么解决,不过问题2在我重装了操作系统和软件后没有出现了,但问题1我觉得不是代码的问题,应该是我对DataGridView控件还不太熟悉,不了解它的一些执行机制,比方说:<br><br>1、DataGridView在允许用户添加行时,在什么情况下添加行有效(这是问题1的关键)<br></P>
<P>2、DataGridView在邦定数据源后是不能通过DataGridView.Rows.Add还添加行的,在AllowUserToAddRow=False的情况下,要如何添加新行呢?(虽然可以用BindingNavigator来添加,但在不用BindingNavigator时又该如何添加呢?)<br></P>
[align=right][color=#000066][此贴子已经被作者于2007-11-2 9:29:36编辑过][/color][/align]

homesite 发表于 2007-11-2 10:21

<P>[attach]29845[/attach]<br>上面是该窗口的截图。<br><br>发现了问题所在:<br><br>当DataGridView的EditMode=EditOnEnter时,只要将光标移到空白行的任何单元格内(没有输入内容),DataGridView并不会再新增加一新行,但DataSet还是会自动新增加一行,如果没有在单元格内输入任何内容,那么该行就是一空行,最后导致再更新时出现了问题,而且是每一次这样的操作就新增加一行。(现在也就知道为什么这样操作一次,再进行排序时会多出一行空白行来了)<br><br>当DataGridView的EditMode=EditOnKeystrokeOrF2 或 EditOnKeystroke时,以上现象不会发生。<br></P>
<P>但问题是我记得之前就是在EditMode=EditOnEnter时都没会有这种情况,会不会还有其它设置会影响到?<br><br>谢谢!</P>
[align=right][color=#000066][此贴子已经被作者于2007-11-2 10:36:38编辑过][/color][/align]

homesite 发表于 2007-11-2 11:15

<P>问题找到了:<BR></P>
<P>'单元格退出编辑模式时<BR>    Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit<BR>        '截掉单元格内容的左右空格字符<BR>        If e.RowIndex = Me.DataGridView1.Rows.Count - 1 Then Exit Sub<BR>        Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString.Trim<BR>        Me.DataGridView1.Rows(e.RowIndex).ErrorText = Nothing<BR>    End Sub<BR></P>
<P>关键就是这句: Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString.Trim<BR><BR>要是没有这句就不会出问题了,但If e.RowIndex = Me.DataGridView1.Rows.Count - 1 Then Exit Sub 已经有个开关,如果是最后一行(即空白行)就不会执行后面的语句了,怎么还会影响到呢?</P>

qlong0728 发表于 2007-11-2 11:43

If e.RowIndex = Me.DataGridView1.Rows.Count - 2 Then Exit Sub  <BR>

homesite 发表于 2007-11-2 13:12

回复:(qlong0728)If e.RowIndex = Me.DataGridView...

<P>这样不对啦,那样的话非空最后一行就不能被操作了(要的只是忽略最后那个空白行!)。<BR>我的做法把出问题的那行代码放到了DataGridView1.CellValueChanged事件中就行了。<BR></P>
<P>当然问题还是很奇怪的,有点奇怪,不知是不是Bug?</P>

<P>另外该窗口为什么在做为子窗口运行时,当行验证信息不全时会发生程序没有响应,CPU占用效达到95%以上的问题也找到了,看下面代码:</P>
<P>  '验证一行的“银行编号”、“开户行”、“帐号”是否为空<BR>    Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating<BR>        If blnLoadForm Then Exit Sub '加载窗体中跳过行验证<BR>        If e.RowIndex = Me.DataGridView1.Rows.Count - 1 Then Exit Sub<BR>        If String.IsNullOrEmpty(Me.DataGridView1.Rows(e.RowIndex).Cells("银行编号").Value.ToString.Trim) Then<BR>            Me.DataGridView1.Rows(e.RowIndex).Cells("银行编号").Selected = True<BR>            Me.DataGridView1.BeginEdit(True)<BR>            Me.DataGridView1.Rows(e.RowIndex).ErrorText = "银行编号不能为空"<BR>            blnRowValidated = False<BR>            e.Cancel = True<BR>            Exit Sub<BR>        End If<BR>        If String.IsNullOrEmpty(Me.DataGridView1.Rows(e.RowIndex).Cells("开户行").Value.ToString.Trim) Then<BR>            Me.DataGridView1.Rows(e.RowIndex).Cells("开户行").Selected = True<BR>            Me.DataGridView1.BeginEdit(True)<BR>            Me.DataGridView1.Rows(e.RowIndex).ErrorText = "开户行不能为空"<BR>            blnRowValidated = False<BR>            e.Cancel = True<BR>            Exit Sub<BR>        End If<BR>        If String.IsNullOrEmpty(Me.DataGridView1.Rows(e.RowIndex).Cells("帐号").Value.ToString.Trim) Then<BR>            Me.DataGridView1.Rows(e.RowIndex).Cells("帐号").Selected = True<BR>            Me.DataGridView1.BeginEdit(True)<BR>            Me.DataGridView1.Rows(e.RowIndex).ErrorText = "帐号不能为空"<BR>            blnRowValidated = False<BR>            e.Cancel = True<BR>            Exit Sub<BR>        End If<BR>        blnRowValidated = True<BR>    End Sub</P>
<P><BR>   从表面上看没点问题,事实在如果该窗口做为独立窗口(即非MDI的子窗口)来运行也是不存在问题的,但现在的问题却是因为e.Cancel=True引起的,e.Cancel=True应该是用来表示行验证没有通过的,现在去掉e.Cancel=True语句就一切正常了,不知何故?会不会是Bug问题?</P>

wmx605 发表于 2007-11-22 19:48

THANKS!!!:victory:

页: [1]

编程论坛