如何使用 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' 此类功能的实现,我想说几点:
您可能不希望每次按下某个键时都对数据库创建一个全新的请求。您可以过滤内存中预加载的数据集以缩短响应时间,但这在数据集非常大且页面使用频繁的情况下可能不合适。
在应用过滤器之前,您可能希望“过滤器”字段中的字符数最少。如果您有数千条记录,那么对所有以 'a' 开头的记录进行筛选就不会特别有用,尤其是因为它会产生一个大页面。您可以仅在字段达到一定长度时才应用过滤器 Javascript.
另一个常见功能是在特定时间段(即 500 毫秒)后应用过滤器而无需进一步输入。如果用户知道他们想要搜索什么,例如'computer',那么对每个字母进行过滤就没有意义(或者 6 次,如果在应用过滤器之前至少需要 3 个字符)。如果您在输入后等待一小段时间再应用过滤器,同时每次按下任何键都重置计时器,那么您将不会进行多次快速重新过滤,这样会降低用户体验,有时会导致不正确的结果(即要应用的最后一个过滤器不是最后一个输入的过滤器)。
如果你只记得其中一个,就记住这一点。好好看看 SQL 注入的概念,并相应地修改你的代码。到处都有关于它的文章,所以探索起来应该不难,但它涉及用户在输入字段中输入恶意命令,然后最终级联到数据库,例如,将 '; drop table UserDe; '
放入搜索字段。
我正在尝试使用我的 gridiview headerTemplate 中的文本框来过滤我的 gridview。我目前正在使用 TextChanged 事件方法来执行此任务,但是当我执行事件方法时,我无法根据 'txtID'
.
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' 此类功能的实现,我想说几点:
您可能不希望每次按下某个键时都对数据库创建一个全新的请求。您可以过滤内存中预加载的数据集以缩短响应时间,但这在数据集非常大且页面使用频繁的情况下可能不合适。
在应用过滤器之前,您可能希望“过滤器”字段中的字符数最少。如果您有数千条记录,那么对所有以 'a' 开头的记录进行筛选就不会特别有用,尤其是因为它会产生一个大页面。您可以仅在字段达到一定长度时才应用过滤器 Javascript.
另一个常见功能是在特定时间段(即 500 毫秒)后应用过滤器而无需进一步输入。如果用户知道他们想要搜索什么,例如'computer',那么对每个字母进行过滤就没有意义(或者 6 次,如果在应用过滤器之前至少需要 3 个字符)。如果您在输入后等待一小段时间再应用过滤器,同时每次按下任何键都重置计时器,那么您将不会进行多次快速重新过滤,这样会降低用户体验,有时会导致不正确的结果(即要应用的最后一个过滤器不是最后一个输入的过滤器)。
如果你只记得其中一个,就记住这一点。好好看看 SQL 注入的概念,并相应地修改你的代码。到处都有关于它的文章,所以探索起来应该不难,但它涉及用户在输入字段中输入恶意命令,然后最终级联到数据库,例如,将
'; drop table UserDe; '
放入搜索字段。