如何使用 TextChanged 事件过滤 gridview?

How to filter gridview using TextChanged event?

我正在尝试使用我的 gridiview headerTemplate 中的文本框来过滤我的 gridview。我目前正在使用 TextChanged 事件方法来执行此任务,但是当我执行事件方法时,我无法根据 '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>

如有任何进一步的建议,我们将不胜感激。谢谢

如果 BindGrid();grdAdjAMT_TextChanged() 在同一个网格上工作,您可能需要这样做:

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

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

您可能还想更改:

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

至:

TextBox txtName = (TextBox)GridView1.HeaderRow.FindControl("txtID");
  • 您可以创建一个 JavaScript 函数,例如:如果我控制 OnClientClick="OnClientSelectedIndexChanged" 例如,我会编写以下内容:

    <script type="text/javascript">
        function OnClientSelectedIndexChanged(sender, args) {
            __doPostBack('ddlSomeDropDownList', '');
        }
    </script>
    
  • 您需要为您的 TextBox 做类似的事情 那么会发生什么是它首先会触发 Page_load 事件,如果设置正确,它将在我的 ddlSomeDropDownList.
  • 事件中触发事件

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

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

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

如其他答案中所述,Javascript 将参与您的解决方案,捕获按键然后向服务器发出请求。如果您 运行 遇到问题,我建议您研究该方法并发布新问题。

关于 'normal' 此类功能的实现,我想说几点:

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

  2. 在应用过滤器之前,您可能希望“过滤器”字段中的字符数最少。如果您有数千条记录,那么对所有以 'a' 开头的记录进行筛选就不会特别有用,尤其是因为它会产生一个大页面。您可以仅在字段达到一定长度时才应用过滤器 Javascript.

  3. 另一个常见功能是在特定时间段(即 500 毫秒)后应用过滤器而无需进一步输入。如果用户知道他们想要搜索什么,例如'computer',那么对每个字母进行过滤就没有意义(或者 6 次,如果在应用过滤器之前至少需要 3 个字符)。如果您在输入后等待一小段时间再应用过滤器,同时每次按下任何键都重置计时器,那么您将不会进行多次快速重新过滤,这样会降低用户体验,有时会导致不正确的结果(即要应用的最后一个过滤器不是最后一个输入的过滤器)。

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