【问题标题】:How to filter gridview using TextChanged event?如何使用 TextChanged 事件过滤 gridview?
【发布时间】:2015-01-20 16:58:29
【问题描述】:

我正在尝试使用 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>

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

【问题讨论】:

  • TextChanged 事件已引发 when the text changes between posts to the server - 您是否希望这会在客户端文本更改时回发?
  • 你熟悉__doPostBack jacascript 方法这听起来像你需要在Page_Load 事件中添加一些if(IsPostBack){} 检查还有FYI 你不需要调用con.Close();,因为它是嵌套在using(){}
  • @barrick,是的,这就是我的目标。感谢您的回复。
  • @MethodMan,感谢您的回复。如果它不是太麻烦,你介意解释一下javascript逻辑,然后我可以使用这种方法继续前进。非常感谢。
  • 我会将它作为示例发布在答案中,这样更容易阅读。我希望这是有道理的。它非常简单,当我不使用的时候我一直使用这样的东西想和Ajax混在一起@

标签: c# asp.net gridview


【解决方案1】:
  • 您可以创建一个 JavaScript 函数,例如:如果我在我的控件上有 OnClientClick="OnClientSelectedIndexChanged",例如,我会编写以下内容:

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

【讨论】:

  • 谢谢,我会放弃的。非常感谢您的回复和帮助。
  • 没问题,如果您有任何问题和/或问题,请告诉我
【解决方案2】:

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

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

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

正如其他答案中已经指出的那样,您的解决方案将涉及 Javascript,捕获按键,然后向服务器发出请求。如果您在那里遇到问题,我建议您研究这种方法并发布新问题。

关于这种功能的“正常”实现,我想说几点:

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

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

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

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

【讨论】:

    【解决方案3】:

    如果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");
    

    【讨论】:

    • 我最初是在回发语句中调用 bindgrid(),但是,当我在 txtID 文本框中输入搜索值时,gridview 会输出整个数据集并且不会将 gridview 过滤为一个记录,正如它所设想的那样。我也不太清楚,是什么导致了事件方法代码中的这种行为。感谢您的回复。
    • AutoPostBack="true" (您拥有)会导致您的帖子返回 OnTextChaned,因此您不需要其他帖子中建议的 javascript。我会将您获取文本框的行更改为 TextBox txtName = (TextBox)GridView1.HeaderRow.FindControl("txtID");字符串 ID = txtName.Text;
    • 感谢您的建议,我选择了 javascript 方法,但我测试了您的方法,这也有效。我希望,我早点看到它。感谢您的帮助和时间。
    猜你喜欢
    • 2015-11-07
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多