我一天中的大部分时间都在尝试通过研究来解决这个问题,但我无法找到适合我当前代码的答案。 我设置了一个由三个下拉列表和一个文本框控制的 GridView。 随着这些变化,这构建了我的 SQL 语句的 WHERE 部分,这样我就可以只提取我想要的数据。
我担心的是,其中大多数会提取数千个数据点,因此我想使用该选项来浏览 GridView 和/或按列对其进行排序。
分页和排序最初可以工作,但现在每次我尝试分页或排序时都只能得到一个空白的 GridView。
ASPX 文件:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestAsset.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<hr />
<div>
<a href="Upload.aspx">Manual Assets</a>
</div>
<hr />
<div>
<asp:DropDownList ID="ddlSource" runat="server" AutoPostBack="true" Width="100px" OnSelectedIndexChanged="ddlSource_SelectedIndexChanged">
/* Removed to Protect the Innocent */
</asp:DropDownList>
<asp:DropDownList ID="ddlAssetType" runat="server" AutoPostBack="true" Width="150px" OnSelectedIndexChanged="ddl_SelectedIndexChanged">
<asp:ListItem Selected="True" Text="ALL" Value="0" />
</asp:DropDownList>
<asp:TextBox ID="tbAsset" runat="server" AutoPostBack="false" Width="500px" OnTextChanged="ddl_SelectedIndexChanged" />
<asp:DropDownList ID="ddlSSP" runat="server" AutoPostBack="true" Width="250px" OnSelectedIndexChanged="ddl_SelectedIndexChanged">
<asp:ListItem Selected="True" Text="ALL" Value="0" />
</asp:DropDownList>
</div>
<hr />
<div>
<asp:GridView ID="gvAllAssets" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="Vertical" PageSize="25" OnPageIndexChanging="gvAllAssets_PageIndexChanging" OnSorting="gvAllAssets_Sorting">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<EditRowStyle BackColor="#999999" />
<EmptyDataTemplate>No Data Found</EmptyDataTemplate>
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<SortedAscendingCellStyle BackColor="#E9E7E2" />
<SortedAscendingHeaderStyle BackColor="#506C8C" />
<SortedDescendingCellStyle BackColor="#FFFDF8" />
<SortedDescendingHeaderStyle BackColor="#6F8DAE" />
<Columns>
<asp:BoundField DataField="SOURCENAME" HeaderText="Source" InsertVisible="false" ReadOnly="true" SortExpression="SOURCENAME">
<ItemStyle Width="100px" Wrap="false" />
</asp:BoundField>
<asp:BoundField DataField="ASSETNAME" HeaderText="Asset Type" InsertVisible="false" ReadOnly="true" SortExpression="ASSETNAME">
<ItemStyle Width="150px" Wrap="false" />
</asp:BoundField>
<asp:BoundField DataField="ASSET" HeaderText="Asset" InsertVisible="false" ReadOnly="true" SortExpression="ASSET">
<ItemStyle Width="500px" Wrap="false" />
</asp:BoundField>
<asp:BoundField DataField="SSP" HeaderText="System Security Plan" InsertVisible="false" ReadOnly="true" SortExpression="SSP">
<ItemStyle Width="250px" Wrap="false" />
</asp:BoundField>
<asp:BoundField DataField="LAST_UPDATED" HeaderText="Last Updated" InsertVisible="false" ReadOnly="true" SortExpression="LAST_UPDATED">
<ItemStyle Width="250px" Wrap="false" />
</asp:BoundField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="dsAllAssets" runat="server" ConnectionString="<%$ ConnectionStrings:TestAssetConnectionString %>" />
</div>
<hr />
<div>
<asp:Label ID="lblSQLStatement" runat="server" />
</div>
<hr />
</form>
</body>
</html>
文件背后的代码:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TestAsset
{
public partial class Default : System.Web.UI.Page
{
private string strWhere = String.Empty;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ddlSource_SelectedIndexChanged(this, EventArgs.Empty);
}
}
protected void ddlSource_SelectedIndexChanged(object sender, EventArgs e)
{
strWhere = String.Empty;
ddl_SelectedIndexChanged(sender, e);
Update_DropdownLists(ddlAssetType, "ASSETID", "ASSETNAME");
Update_DropdownLists(ddlSSP, "DENSE_RANK() OVER (ORDER BY SSP) AS Row", "SSP");
}
protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
strWhere = String.Empty;
if (ddlSource.SelectedValue != "0")
{
if (strWhere == String.Empty)
{
strWhere = "WHERE SDBs.SOURCE = " + ddlSource.SelectedValue;
}
else
{
strWhere = strWhere + " AND SDBs.SOURCE = " + ddlSource.SelectedValue;
}
}
if (ddlAssetType.SelectedValue != "0")
{
if (strWhere == String.Empty)
{
strWhere = "WHERE Assets.ASSET_TYPE = " + ddlAssetType.SelectedValue;
}
else
{
strWhere = strWhere + " AND Assets.ASSET_TYPE = " + ddlAssetType.SelectedValue;
}
}
if (tbAsset.Text != "")
{
if (strWhere == String.Empty)
{
strWhere = "WHERE Assets.ASSET LIKE '%" + tbAsset.Text + "%'";
}
else
{
strWhere = strWhere + " AND Assets.ASSET LIKE '%" + tbAsset.Text + "%'";
}
}
if (ddlSSP.SelectedValue != "0")
{
if (strWhere == String.Empty)
{
strWhere = "WHERE Assets.SSP = '" + ddlSSP.SelectedItem + "'";
}
else
{
strWhere = strWhere + " AND Assets.SSP = '" + ddlSSP.SelectedItem + "'";
}
}
Update_GridView();
}
protected void Update_GridView()
{
string selectStatement =
"SELECT " +
"SDBNames.SOURCENAME AS 'SOURCENAME', " +
"AssetNames.ASSETNAME AS 'ASSETNAME', " +
"Assets.ASSET AS 'ASSET', " +
"Assets.SSP AS 'SSP', " +
"SDBs.LAST_UPDATED AS 'LAST_UPDATED' " +
"FROM " +
"Assets " +
"INNER JOIN AssetNames " +
"ON Assets.ASSET_TYPE = AssetNames.ASSETID " +
"INNER JOIN SDBs " +
"ON Assets.SDBID = SDBs.ID " +
"INNER JOIN SDBNames " +
"ON SDBs.SOURCE = SDBNames.SOURCEID " +
strWhere + " ;";
lblSQLStatement.Text = selectStatement;
dsAllAssets.SelectCommand = selectStatement;
DataView dv = (DataView)dsAllAssets.Select(DataSourceSelectArguments.Empty);
DataTable dt = dv.ToTable();
dsAllAssets.DataBind();
if (dt.Rows.Count > 0)
{
gvAllAssets.DataSourceID = "dsAllAssets";
gvAllAssets.DataBind();
}
else
{
gvAllAssets.DataSourceID = "";
ShowNoResultFound(dt, gvAllAssets);
gvAllAssets.Rows[0].Cells[0].Width = 1250;
}
}
protected void Update_DropdownLists(DropDownList ddl, string valueField, string textField)
{
string modifiedValue;
if (valueField.Contains(" AS "))
{
modifiedValue = valueField.Split(' ').Last();
}
else
{
modifiedValue = valueField;
}
string strSSPCommand = "" +
"SELECT DISTINCT " +
valueField + ", " +
textField + " " +
"FROM " +
"Assets " +
"INNER JOIN AssetNames " +
"ON Assets.ASSET_TYPE = AssetNames.ASSETID " +
"INNER JOIN SDBs " +
"ON Assets.SDBID = SDBs.ID " +
"INNER JOIN SDBNames " +
"ON SDBs.SOURCE = SDBNames.SOURCEID " +
strWhere + " " +
"ORDER BY " + modifiedValue + " ;";
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["TestAssetConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand(strSSPCommand, con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
ddl.DataValueField = modifiedValue;
ddl.DataTextField = textField;
ddl.DataSource = dt;
ddl.DataBind();
ddl.Items.Insert(0, new ListItem("ALL", "0"));
}
protected void ShowNoResultFound(DataTable source, GridView target)
{
source.Rows.Add(source.NewRow());
target.DataSource = source;
target.DataBind();
int columnsCount = target.Columns.Count;
target.Rows[0].Cells.Clear();
target.Rows[0].Cells.Add(new TableCell());
target.Rows[0].Cells[0].ColumnSpan = columnsCount;
target.Rows[0].Cells[0].ForeColor = System.Drawing.Color.Red;
target.Rows[0].Cells[0].Font.Bold = true;
target.Rows[0].Cells[0].HorizontalAlign = HorizontalAlign.Center;
target.Rows[0].Cells[0].Text = "NO RESULTS FOUND!";
}
protected void gvAllAssets_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvAllAssets.PageIndex = e.NewPageIndex;
gvAllAssets.DataBind();
}
protected void gvAllAssets_Sorting(object sender, GridViewSortEventArgs e)
{
gvAllAssets.Sort(e.SortExpression, e.SortDirection);
gvAllAssets.DataBind();
}
}
}
我现在承认,我在 ASP.net 方面并不是最好的,但有人告诉我我需要做一些“东西”来显示我们在数据库中拥有的内容。 我对搜索选项不太热心,并花了一段时间才使其正常工作。 然后我继续恢复代码的备份副本,它再次可以进行搜索、分页和排序...因为我再次在 HTML 代码中设置了 DataSourceID,我最初将其取出,以便它会显示一些有趣的内容如果没有显示数据。 所以暂时把它留在那里并继续前进!
首先要尝试的是,使用 GridView 的
.DataSource
属性,而不是 .DataSourceID
。 提供 DataSourceID
会导致在页面生命周期期间发生某些自动绑定操作。 由于您尝试通过特定输入事件自行管理数据绑定,因此您不希望调用其他数据绑定。
而且——你真的让自己的事情变得更加困难。 当您尝试通过用户输入减少数据集时,存储过程的效果要好得多。更好地利用 SqlDataSource 的全部功能来接受 WebControls 作为输入参数,例如:
<asp:SqlDataSource ID="dsAllAssets" runat="server" ConnectionString="<%$ ConnectionStrings:TestAssetConnectionString %>"
SelectCommand="sp_SomeProcedureYouCreate"
SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:ControlParameter Name="sp_var_1" ControlID="ddlAssetType" PropertyName="SelectedValue" Type="Int32" />
<asp:ControlParameter Name="sp_var_2" ControlID="tbAsset" PropertyName="Text" Type="String" />
<asp:ControlParameter Name="sp_var_3" ControlID="ddlSSP" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
这样你可以这样设置:
<asp:GridView ID="gvAllAssets" runat="server" DataSourceID="dsAllAssets" ... />
将输入
DropDownList
和 TextBox
控件设置为在更改后回发以重新绑定。 或者设置一个按钮,仅在用户做出输入选择后回发一次