如何使用TextChanged事件过滤gridview?

时间:2015-01-20 16:58:29

标签: c# asp.net gridview

我正在尝试使用gridiview headerTemplate中的文本框过滤我的gridview。我目前正在使用TextChanged事件方法来执行此任务,但是当我执行events方法时,我无法在'txtID'中基于搜索输入过滤gridiview。

protected void grdAdjAMT_TextChanged(object sender, EventArgs e)
    {
        TextBox txtName = (TextBox)GridView1.Rows[(0)].FindControl("txtID");

        string strConnString = ConfigurationManager.ConnectionStrings["####"].ConnectionString;
        using (SqlConnection con = new SqlConnection(strConnString))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.CommandText = "select u.[uID], u.[uForenames], 
                    u.[uSurname], u.[uCompany], u.[uEmailAddress], 
                    s.[sStartDate] 
                from [dbo].[UserDe] 
                where u.[uID] like '%" + txtName + "%' 
                order by s.[sStartDate] desc";

                cmd.Connection = con;
                con.Open();
                GridView1.DataSource = cmd.ExecuteReader();
                GridView1.DataBind();
                con.Close();
            }
        }
    }

protected void Page_Load(object sender, EventArgs e)
    {
        BindGrid();

    }

我调试了我的脚本,发现调试器只通过了pageload和BindGrid方法,但它没有通过" grdAdjAMT_TextChanged"方法。我也尝试单独调试textChange方法,但仍然没有任何反应。

 <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="uID" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" CellPadding="4" ForeColor="#333333" GridLines="None" >
        <AlternatingRowStyle BackColor="White" />
    <Columns>

        <asp:TemplateField HeaderText="ID" SortExpression="ID">
        <HeaderTemplate>
        <asp:Label ID="Label1" runat="server" Text="ID"></asp:Label><br />
            <asp:TextBox ID="txtID" runat="server" OnTextChanged="grdAdjAMT_TextChanged" AutoPostBack="true"></asp:TextBox>
        </HeaderTemplate>
            <ItemTemplate>
                <asp:Label ID="Label2" runat="server" Text='<%# Bind("uID") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>

非常感谢任何进一步的建议。感谢

3 个答案:

答案 0 :(得分:1)

如果BindGrid();grdAdjAMT_TextChanged()处于同一网格,您可能需要这样做:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {         
        BindGrid();
    }
}

在帖子后面,Page_Load在OnTextChanged事件之前运行。因此,如果您在每个帖子上绑定网格,它将清除网格中的搜索文本。然后当它检查TextChanged时,它会将空字符串与空字符串进行比较,并且说没有变化,所以它不会运行该事件。

您可能还想更改:

TextBox txtName = (TextBox)GridView1.Rows[(0)].FindControl("txtID");

为:

TextBox txtName = (TextBox)GridView1.HeaderRow.FindControl("txtID");

答案 1 :(得分:1)

  • 您可以创建一个JavaScript函数,例如:如果我在我的控件OnClientClick="OnClientSelectedIndexChanged"上,我会写下以下内容:

    <script type="text/javascript">
        function OnClientSelectedIndexChanged(sender, args) {
            __doPostBack('ddlSomeDropDownList', '');
        }
    </script>
    
  • 您需要为TextBox执行类似的操作 然后会发生什么事情,它会首先点击Page_load事件,如果它正确设置,它将在我ddlSomeDropDownList的情况下点击事件。

答案 2 :(得分:1)

这里简短的回答是,仅使用服务器端代码无法实现您想要实现的目标(重新获得与给定过滤器匹配的结果)。

作为无状态,ASP.NET运行时只会知道它在发布到表单时从表单接收的值,以及它在呈现页面时创建的值。因此,如果没有回复,即通过“过滤器”按钮,它将根本不知道文本是否发生了变化。实际上,TextChanged事件仅适用于Viewstate属性,这是一个潜在的大型base-64编码字符串,由运行时嵌入到表单中以保存控件的“先前”值等

按下按钮是客户端操作,因此服务器对此一无所知。证明这一点的一点是,虽然System.Windows.Forms中有Control.KeyPress事件,但System.Web.UI.WebControls中没有等效事件。

正如其他答案所示,Javascript将参与您的解决方案,捕获按键,然后向服务器发送请求。如果你遇到问题,我建议研究这种方法并发布新问题。

关于这种功能的“正常”实现,我要提出几点:

  1. 每次按下某个键时,您可能不希望为数据库创建全新的请求。您可以在内存中过滤预先加载的数据集以缩短响应时间,但这可能不适用于数据集非常大且页面频繁使用的情况。

  2. 在应用过滤器之前,您可能希望在“过滤器”字段中包含最少数量的字符。如果您有数千条记录,那么以“a”开头的所有记录的过滤器将不会特别有用,尤其是因为它会导致大页面。只有当字段使用Javascript轻松达到一定长度时,才可以应用过滤器。

  3. 另一个常见特征是在特定时间段(即500毫秒)之后应用滤波器而无需进一步输入。如果用户知道他们想要搜索什么,例如'计算机',那么每个字母上都没有过滤点(如果你在应用过滤器之前需要至少3个字符,则为6次)。如果您在应用过滤器之前等待一小段时间,在每次按下任何按键时重置定时器,那么您将不会进行多次快速重新过滤,这样会降低用户体验,有时会导致错误的结果(即要应用的最后一个过滤器不是最后输入的过滤器。

  4. 如果您只记得其中一点,请记住这一点。仔细研究SQL注入的概念,并相应地修改代码。关于它的文章到处都是,所以它应该不难探索,但它涉及用户将恶意命令输入到输入字段中,然后最终级联到数据库,例如,将'; drop table UserDe; '放入搜索字段。