使用 vb.net 根据 SQL 数据库中存在的记录动态显示/隐藏 DataGrid 按钮列时遇到问题
Posted
技术标签:
【中文标题】使用 vb.net 根据 SQL 数据库中存在的记录动态显示/隐藏 DataGrid 按钮列时遇到问题【英文标题】:Having trouble dynamically show/hide DataGrid buttoncolumn based on record existing in SQL database using vb.net 【发布时间】:2015-05-06 23:35:09 【问题描述】:我正在使用 Visual Studio 2008 和 vb.net。我有一个包含几列的数据网格,有问题的列是一个 ButtonColumn 控件。当前按钮出现在每一行上,然后链接到另一个页面,其中显示有关名称的数据(在另一列中)被选中。问题是当下一页上的查询不包含所选行的数据时,页面会抛出错误。
我的(首选)解决方案是在 ItemDataBound 事件期间(在切换页面之前)首先检查记录是否存在,并将按钮隐藏在不存在记录的行中,并在它们存在的位置显示按钮。问题是按钮的显示和隐藏不一致。
我不是 vb 程序员,谁能检查我的代码,看看我哪里出错了。
我已经咨询了谷歌并使用这些链接来了解其中的一些内容: http://www.codeproject.com/Articles/8666/Practical-use-of-the-DataGrid-s-ItemDataBound-even
http://www.thescarms.com/dotnet/WebDataGrid.aspx
更新: 解决方案在代码 #1 和 html 中进行了更新。 SQL
ALTER PROCEDURE [dbo].[VerifyRecords]
@Name VarChar (50),
@RecordExists Int output
AS
BEGIN
SET NOCOUNT ON;
SELECT top 1 * from tblRecords where Name = @Name
If @@ROWCOUNT = 0
begin
Select @RecordExists = 5 --record does not exist
end
else
begin
Select @RecordExists = 1 --record exists
end
-- --ALTERNATIVE QUERY
--if not exists (select 1 from tblRecords where Name = @Name)
-- begin
-- Select @RecordExists = 5 --print 'no record found'
-- end
--else
-- begin
-- Select @RecordExists = 1 --print 'record exists'
-- end
END
enter code here
1.代码在调用类
Protected Sub DataGrid1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemDataBound
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim strName As String = ""
Dim blnHasRecord As Boolean
' *** UPDATED CODE HERE ***
Dim lblName As Label = e.Item.FindControl("lblName")
strName = lblName.Text.ToString()
Dim oRecord As DataAccessLib.SqlConn = New DataAccessLib.SqlConn()
blnHasRecord = oRecord.VerifyRecordExists(strName)
DirectCast(e.Item.Cells(9).Controls(0), Button).Visible = blnHasRecord
End If
End Sub
2.代码在数据访问类
Function VerifyRecordExists (ByVal name As String) As Boolean
Try
Dim recordExists As Boolean
Dim result As Int32
'connection
Using conStr As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("SomeConnectionString").ConnectionString)
'open connection
conStr.Open()
'command
Dim cmdVerifyRecordExists As SqlClient.SqlCommand = New SqlClient.SqlCommand("VerifyRecordExists", conStr)
cmdVerifyRecordExists.CommandType = CommandType.StoredProcedure
'input parameter
cmdVerifyRecordExists.Parameters.Add("@Name", SqlDbType.VarChar).Value = name
'output parameter
cmdVerifyRecordExists.Parameters.Add("@RecordExists", SqlDbType.Int)
cmdVerifyRecordExists.Parameters("@RecordExists").Direction = ParameterDirection.Output
'execute query
cmdVerifyRecordExists.ExecuteNonQuery()
result = cmdVerifyRecordExists.Parameters("@RecordExists").Value
End Using
If (name <> Nothing) Then
If (result = 5) Then 'result = 5; no records found
recordExists = False
Else
' result = 1; records found
recordExists = True
Return recordExists
End If
End If
Catch ex As System.Data.SqlClient.SqlException
' code here removed for breivity
End Try
End Function
3.CODE绑定DataGrid
Sub getRecords(ByVal strSortField As String)
Dim sortdir As Integer
DataGrid1.DataSource = Nothing
Using conStr As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("SomeConnectionString").ConnectionString)
Try
If USERLEVEL > 2 Then
conStr.Open()
Dim cmdSelectRecords As New SqlCommand("SelectAllNames", conStr)
cmdSelectRecords.CommandType = CommandType.StoredProcedure
SqlDataAdapter1.Fill(DsRecords1)
Dim objDataView As DataView = DsRecords1.Tables("vwRecordsList").DefaultView
DataGrid1.DataSource = Nothing
DataGrid1.DataSource = objDataView
If Session("sortdir") = Nothing Then
Session("sortdir") = 1 ' 1=ASC, 0=DESC
Else
sortdir = Session("sortdir")
End If
If sortdir = 1 Then
Session("sortdir") = 0
objDataView.Sort = strSortField & " DESC"
ElseIf sortdir = 0 Then
Session("sortdir") = 1
objDataView.Sort = strSortField & " ASC"
End If
DataGrid1.DataBind()
ElseIf USERLEVEL = 2 Then
Dim cmdSelectRecords As New SqlCommand("SelectNamesBySuper", conStr)
cmdSelectRecords.CommandType = CommandType.StoredProcedure
cmdSelectRecords.Parameters.Add("@UID", SqlDbType.Int).Value = uID
SqlDataAdapter1.Fill(DsRecords1)
Dim objDataView As DataView = DsRecords1.Tables("vwRecordsList ").DefaultView
DataGrid1.DataSource = Nothing
DataGrid1.DataSource = objDataView
If Session("sortdir") = Nothing Then
Session("sortdir") = 1
Else
sortdir = Session("sortdir")
End If
If sortdir = 1 Then
Session("sortdir") = 0
objDataView.Sort = strSortField & " DESC"
ElseIf sortdir = 0 Then
Session("sortdir") = 1
objDataView.Sort = strSortField & " ASC"
End If
DataGrid1.DataBind()
Else
Response.Redirect("AccessDenied.aspx")
End If
Catch ex As System.Data.SqlClient.SqlException
' error code left out for demo purposes
End If
End Try
End Using
End Sub
HTML 我只提供 DataGrid1 的相关列,因为网格本身加载得很好。是我在后面的代码中对这一列的修改还不正确。
更新:我用 TemplateColumn 替换了 boundcolumn:
<%--<asp:BoundColumn DataField="Name" HeaderText=" Name" SortExpression="Name" Visible="False" />--%>
<asp:TemplateColumn>
<ItemTemplate>
<asp:Label id="lblName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
【问题讨论】:
按钮何时显示和隐藏不一致?页面加载后或页面中发生类似按钮时。 在 DirectCast 上尝试 GridItem.Cells(9).Controls(0) 而不是更改 e.Item.Cells(9).Controls(0) 哦,很好@DanielVorph,这成功了!请给出答案,我会接受。但是现在,当使用 Name 列时,第一行变成了最后一行,并且在应该隐藏时错误地显示了一个按钮。所有其他行以 ASC 或 DESC 顺序正确显示按钮/无按钮。当我求助于原始(asc)排序时,第一行再次正确。如果有兴趣看一下,我为此发布了排序代码 #3。 Put DirectCast(GridItem.Cells(9).Controls(0), Button).Visible = blnHasRecord quit if else 语句,你调试最后一行发生了什么,strName 值是多少? ItemDataBound 事件会为数据源中的每一行触发,然后您在其中有一个循环,您应该退出循环并仅使用当前项目 e.Item 【参考方案1】:我希望可以发布 DanielVorph 提供的答案。 “数据源中的每一行都会触发 ItemDataBound 事件,然后您在其中有一个循环,您应该退出循环并仅使用当前项目 e.Item– DanielVorphMay 8 at 21:21”。 在除此之外,我将 DataGrid1 中的 BoundColumn
替换为 TemplateColumn
。
VB.NET:
Protected Sub DataGrid1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemDataBound
'Get only non header or footer rows
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim strName As String 'column[2]
Dim blnHasRecord As Boolean
'get Name
Dim lblName As Label = e.Item.FindControl("lblName")
strName = lblName.Text.ToString()
'query sql - does record exist for this Name?
Dim oRecord As DataAccessLib.SqlConn = New DataAccessLib.SqlConn()
blnHasRecord = oRecord. VerifyRecordExists (strName)
'Show or hide button based on records existence
DirectCast(e.Item.Cells(9).Controls(0), Button).Visible = blnHasRecord 'column[9]
End If
End Sub
ASPX: 删除此类列:
<asp:BoundColumn DataField="Name" HeaderText="Name" SortExpression="Name" Visible="False" />
添加这种类型的列:
<asp:TemplateColumn>
<ItemTemplate>
<asp:Label id="lblName" runat="server" Text='<%#DataBinder.Eval
(Container.DataItem, "Name") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
【讨论】:
以上是关于使用 vb.net 根据 SQL 数据库中存在的记录动态显示/隐藏 DataGrid 按钮列时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章
从 VB.net 连接到 SQL 数据库时,“行/列不存在数据”