ASP.NET 如果文本框为空,则 GridView 不会因更改 SqlDataSource.SelectCommand 而填充

ASP.NET GridView won't populate from changing SqlDataSource.SelectCommand if Textbox is empty

我正在使用文本框和下拉列表来过滤数据库搜索。我使用带有空白 SelectCommand 的 SQLDataSource,然后根据用户输入的内容和在 DropDownList 中选择的内容在代码隐藏中设置命令。我在代码隐藏中的 IF 语句仅在 txtFindBook != "".

时有效

在我继续解释之前,这是我的代码:

Default.aspx

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">

<div class="jumbotron">
    <h1>Find a book...</h1>
    <p>
        <asp:TextBox ID="txtFindBook" runat="server" Width="700px"></asp:TextBox>

        <asp:DropDownList ID="ddlGenres" runat="server"></asp:DropDownList>

        <asp:Button ID="btnFindBook" runat="server" Text="Search" OnClick="btnFindBook_Click" Height="36px"  />

    <p>Enter your search terms in the box above, then click "Search" to begin your search.</p>
    <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
</div>

<div class="searchresults">
    <asp:GridView ID="gvSearchResults" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="SqlDataSourceSearchResults">
        <Columns>
            <asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True" InsertVisible="False" SortExpression="ID"></asp:BoundField>
            <asp:BoundField DataField="BookID" HeaderText="BookID" SortExpression="BookID"></asp:BoundField>
            <asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title"></asp:BoundField>
            <asp:BoundField DataField="Author" HeaderText="Author" SortExpression="Author"></asp:BoundField>
            <asp:BoundField DataField="ISBN_10" HeaderText="ISBN_10" SortExpression="ISBN_10"></asp:BoundField>
            <asp:BoundField DataField="ISBN_13" HeaderText="ISBN_13" SortExpression="ISBN_13"></asp:BoundField>
            <asp:BoundField DataField="Dewey" HeaderText="Dewey" SortExpression="Dewey"></asp:BoundField>
            <asp:BoundField DataField="Genre" HeaderText="Genre" SortExpression="Genre"></asp:BoundField>
            <asp:CheckBoxField DataField="isCheckedOut" HeaderText="isCheckedOut" SortExpression="isCheckedOut"></asp:CheckBoxField>
            <asp:BoundField DataField="Checked_Out_To_Whome" HeaderText="Checked_Out_To_Whome" SortExpression="Checked_Out_To_Whome"></asp:BoundField>
            <asp:BoundField DataField="Due_Date" HeaderText="Due_Date" SortExpression="Due_Date"></asp:BoundField>
        </Columns>
    </asp:GridView>
    <asp:SqlDataSource runat="server" ID="SqlDataSourceSearchResults" ConnectionString='<%$ ConnectionStrings:DefaultConnection %>' SelectCommand="">
        <SelectParameters>
            <asp:ControlParameter ControlID="txtFindBook" PropertyName="Text" Name="Title" Type="String"></asp:ControlParameter>
            <asp:ControlParameter ControlID="ddlGenres" PropertyName="SelectedValue" DefaultValue="Select Genre" Name="Genre" Type="String"></asp:ControlParameter>
        </SelectParameters>
    </asp:SqlDataSource>
</div>

Default.aspx.cs

public partial class _Default : Page
{
    static string connString = System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
    SqlConnection conn = new SqlConnection(connString);

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            /*There is no point in populating
            the dropdownlist everytime there
            is a post back. */

            populateddlGenres();
        }

    }
    protected void btnFindBook_Click(object sender, EventArgs e)
    {
        if (txtFindBook.Text != "" && ddlGenres.SelectedItem.Text != "Select Genre")
        {
            SqlDataSourceSearchResults.SelectCommand = "SELECT * FROM [Books] WHERE (([Title] LIKE '%' + @Title + '%') AND ([Genre] = @Genre)) ORDER BY [Title]";
            Label1.Text = "If Statement 1.";
        }

        else if (txtFindBook.Text == "" && ddlGenres.SelectedItem.Text != "Select Genre")
        {
            Label1.Text = "If Statement 2.";
            SqlDataSourceSearchResults.SelectCommand = "SELECT * FROM [Books] WHERE ([Genre] = @Genre)";
        }

        else if (txtFindBook.Text == "" && ddlGenres.SelectedItem.Text == "Select Genre")
        {
            SqlDataSourceSearchResults.SelectCommand = "SELECT * FROM [Books]";
            Label1.Text = "If Statement 3.";
        }

        else if(txtFindBook.Text != "" && ddlGenres.SelectedItem.Text == "Select Genre")
        {
            SqlDataSourceSearchResults.SelectCommand = "SELECT * FROM [Books] WHERE ([Title] LIKE '%' + @Title + '%') ORDER BY [Title]";
            Label1.Text = "Original.";
        }
    }

    private void populateddlGenres()
    {
        try
        {

            using (SqlConnection con = new SqlConnection(connString))
            {
                SqlCommand cmd = new SqlCommand("SELECT * FROM Genres", con);
                con.Open();
                ddlGenres.DataSource = cmd.ExecuteReader();
                ddlGenres.DataTextField = "GenreText";
                //ddlGenres.DataValueField = ""; //We aren't using this because the text is it's own value.
                ddlGenres.DataBind(); //MUST GO LAST!

            }

        }
        catch (Exception ex)
        {
            // Handle the error
        }

        ddlGenres.Items.Insert(0, new ListItem("Select Genre", "0"));

    }
}

现在如果我添加 txtFindBook.text = "a";在 If 语句 2 和 3 的开头,它实际上会在 PostBack 上填充 gvSearchResults。

有没有什么方法可以让 If 语句 2 和 3 在保持 txtFindBook.Text 空白的情况下工作?

修改您的 SqlDataSource,将默认值 NULL 添加到您在其上定义的标题 属性,这应该可以解决问题。你不需要标签,反正我没看懂标签的事。

<asp:SqlDataSource runat="server" ID="SqlDataSourceSearchResults" ConnectionString='<%$ ConnectionStrings:DefaultConnection %>' SelectCommand="">
    <SelectParameters>
        <asp:ControlParameter ControlID="txtFindBook" PropertyName="Text" DefaultValue="NULL" Name="Title" Type="String"></asp:ControlParameter>
        <asp:ControlParameter ControlID="ddlGenres" PropertyName="SelectedValue" DefaultValue="Select Genre" Name="Genre" Type="String"></asp:ControlParameter>
    </SelectParameters>
</asp:SqlDataSource>