【问题标题】:Gridview event not firingGridview 事件未触发
【发布时间】:2012-03-30 03:10:51
【问题描述】:

我有一个要求,如果我的网格视图中的任何值发生变化,我必须更新一个文本框。我有一个有 2 行的网格视图 ..

一个带有标签的模板字段和另一个带有文本框的模板字段...

我的网格视图看起来像

                   name                 value
                   a                     (empty textbox)
                   b                     (empty textbox)
                   c                      (empty textbox)

现在当用户在文本框中输入一个值时,它应该自动更新另一个与之链接的文本框。

我的问题是,当有人在文本框中输入一个值时,应该触发一个事件!

(我从数据库中获取名称 a、b、c)。我不想有编辑链接或更新链接,因为要输入的所有值都是强制性的!

我尝试了 Grid_SelectedIndexChanged1 但这没有触发.. 是否有什么我遗漏或我需要更改以便触发 evant 并且我可以更新另一个文本框??

我是 ASP.NET 新手,所以请帮忙!

提前致谢!

【问题讨论】:

  • TextBox 有一个 AutoPostback 属性将其设置为 true 并处理 TextChanged 事件或使用 javascript 在客户端执行。
  • 请告诉我链接文本框是什么意思?
  • 我也试过了.. 但是我怎么知道哪些行文本框改变了?
  • @ persian dev 我还有其他文本框需要更新我从这些字段中获得的值。我有一个文本要使用这些文本框字段提供的值进行编辑!
  • selectedindexchanged 在所选行的索引更改时触发,在此实例中未发生。如果您所做的只是用相同的文本更新另一个 UI 元素,那么在服务器上进行一次访问就太过分了。 javascript,更具体地说 jquery 将是一个更好的解决方案。

标签: c# asp.net gridview


【解决方案1】:

如果要在文本更改时触发更新,则应使用TextBoxOnTextChanged 事件,并将AutoPostBack 设置为true。

编辑

为避免在此重复工作,使用上述方法,您可以使用 Pankaj Garg 在他的回答中概述的技术找到行索引:

int rowIndex = ((GridViewRow)((TextBox)sender).NamingContainer).RowIndex;

这种方法的最大警告是它不能容忍标记的变化。如果您要将TextBox 包装在另一个实现INamingContainer 的控件中,则上面的示例将中断。例如:

<asp:TemplateField>
    <asp:Panel ID="Panel1" runat="server"> <!-- becomes the naming container -->
        <asp:TextBox ID="TextBox1" runat="server" onchange='valueChanged(<%# Container.ItemIndex %>);' />
    </asp:Panel>
</asp:TemplateField>

话虽如此,您可能希望相应地标记您的标记,以便其他开发人员知道在进行更改时要小心。

编辑

作为替代方案,您也可以使用 TextBoxonchange 事件在 JavaScript 中触发回发:

<script type="text/javascript">
    valueChanged = function(rowIndex){
        __doPostBack("<%= GridView1.ClientID %>", rowIndex);
    }
</script>
<asp:GridView ID="GridView1" runat="server" DataKeyNames="ID" ...>
    <Columns>
        <asp:TemplateField>
            <asp:TextBox ID="TextBox1" runat="server" onchange='valueChanged(<%# Container.ItemIndex %>);' />
        </asp:TemplateField>
    </Columns>
</asp:GridView>    

在代码隐藏中,覆盖RaisePostBackEvent 方法,并将更新逻辑放在那里:

protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
{
    base.RaisePostBackEvent(source, eventArgument);

    if (source == GridView1)
    {
        int rowIndex = int.Parse(eventArgument);

        TextBox txt = GridView1.Rows[rowIndex].FindControl("TextBox1") as TextBox;
        if (txt != null)
        {
            var id = (int)GridView1.DataKeys[rowIndex]["ID"];
            var text = txt.Text.Trim();

            //update the database
        } 
    }    
}

【讨论】:

  • 如果 GridView 在 UpdatePanel 中(只是猜测),他还需要为 GridView 的 RowCommand 添加触发器。
  • @感谢您的回复,问题是我知道我现在拥有的文本框的哪个值..例如我必须知道..a的值=输入的值!
  • 我不确定你的意思。你是说需要知道TextBox对应哪一行?
  • 嗨@James - 如果您要将TextBox 包装在另一个实现INamingContainer 的控件中,上面的示例将会中断。 请您说得更准确些。抱歉没有得到这句话。
  • 如果出于某种原因他将TextBox 放在Panel 或另一个实现INamingContainer 的控件中,代码就会中断。
【解决方案2】:

您可以像下面这样检查当前行索引...

((GridViewRow)((TextBox)sender).NamingContainer).RowIndex

OnTextChanged 事件创建一个处理程序并设置AutoPostBack Property True

protected void TextBox_TextChanged(object sender, EventArgs e)
{
     int CurrentGridIndex = ((GridViewRow)((TextBox)sender).NamingContainer).RowIndex
}

【讨论】:

  • @pankaj... 我尝试这样做,并尝试访问返回空字符串的单元格!
  • 我做了一些类似 GridViewRow gv = Grid.Rows[CurrentGridIndex];字符串值 = gv.Cells[0].Text;
  • 您可以在单元格中找到控件,例如(ControlType)gv.FindControl("YourID")
猜你喜欢
  • 2012-01-19
  • 2012-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多