【问题标题】:Button Click in a TableCell never fires and table disappearsTableCell 中的按钮单击永远不会触发并且表格消失
【发布时间】:2015-06-03 16:42:40
【问题描述】:

我的 ASP.NET Webforms 应用程序,我有一个 table,我在其中动态添加所有数据。一行在每个单元格中包含Buttons。我希望按钮在用户单击它时触发 onclick 事件。但是,使用下面的代码,事件永远不会触发并且表格消失。这是代码:

    <asp:Table ID="floorTable" runat="server"  Width="100%" GridLines="Both">
    </asp:Table>

在代码后面

   // This method is called on a DropDownList SelectedItemChanged Event - so
   // the buttons cannot be created in Page_Load or so. Have to create 
   // totally based on the DropDown selected item.
    private void PopulateFloorRow(int floorNo, FloorPattern fp)
    {
        int cols = fp.UnitPattern.Count;

        // HEADER ROW
        TableRow thead = new TableRow(); 
        thead.Width = Unit.Percentage(100);
        thead.TableSection = TableRowSection.TableHeader;
        TableCell theadCell = new TableCell();
        theadCell.ColumnSpan = cols;
        Label title = new Label();
        title.Text = "Floor # " + floorNo;
        theadCell.Controls.Add(title);
        thead.Controls.Add(theadCell);

        TableRow planRow = GetFloorPlan(floorNo, fp);

        TableRow tr = new TableRow();
        TableCell tc = null;
        int tcWidPerc = (int)fp.UnitPattern.Count / 100;

        foreach (UnitPattern up in fp.UnitPattern)
        {                
            tc = new TableCell();

            Button imgBtn = new Button();

            // On Adding BELOW Line - ERROR - 0x800a1391 - JavaScript runtime error: 'UnitLinkClicked' is undefined
            //imgBtn.Attributes.Add("onClick", "UnitLinkClicked(this)");

            imgBtn.CommandArgument = up.UnitPatternId.ToString(); // I want to know which button is pressed. So, sort of Tag
            imgBtn.Click += new EventHandler(UnitLinkClicked);
            imgBtn.BorderWidth = Unit.Pixel(10);
            imgBtn.BorderColor = Color.Transparent;
            imgBtn.Width = Unit.Percentage(100);
            if (up.UnitNo != null)
            {
                imgBtn.Text = up.UnitNo;
            }

            tc.Controls.Add(imgBtn);

            tr.Controls.Add(tc);
        }

        floorTable.Rows.Add(thead);
        floorTable.Rows.Add(planRow);
        floorTable.Rows.Add(tr);

        // Create Footer
        PopulateTableFooter(cols);

    }

    protected void UnitLinkClicked(object sender, EventArgs e)
    {
        Button btn = (Button)(sender);
        string upId = btn.CommandArgument;

        System.Diagnostics.Debug.WriteLine("LINK Button clicked Of UP ID :" + upId);
    }

编辑:添加了 SELECTEDiINDEXCHANGED 的代码

我的 DropDown_SelectedIndexChanged 代码:

    protected void floorDropDownList_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (selectedProject == null)
            selectedProject = _db.Projects.Find(projectsList.SelectedValue);

        System.Diagnostics.Debug.WriteLine("SELCTED Project = " + selectedProject.ProjectId);

        // "Select Floor" is selected, so Hide floor Table
        if (floorDropDownList.SelectedValue == "-1")
        {
            floorTable.Visible = false;
        }
        else
        {
            int floorNo = int.Parse(floorDropDownList.SelectedValue);
            if (floorNo > 0)
            {
                PopulateFloorRow(floorNo, (FloorPattern)selectedProject.FloorPattern.ElementAt(floorNo - 1));
            }
        }
    }

如果我在下拉列表中选择了“3”,表格将按预期显示。我点击一个按钮,表格消失了,但下拉列表中的值仍然只有“3”。

编辑部分

使用上面的代码,当我点击一个按钮时,UnitLinkClicked 事件永远不会被触发(我添加了断点)并且整个表格消失了。

你能说这会是什么问题吗?默认情况下,按钮是 AutoPostBack 并且它也没有该属性。我在这里缺少什么以及如何解决这个问题。几天以来我一直坚持这一点并试图弄清楚。

非常感谢任何帮助。 谢谢

【问题讨论】:

  • 为什么需要动态控件?
  • 可能发布您的下拉更改事件代码。

标签: c# asp.net button dynamic onclick


【解决方案1】:

您需要为按钮设置一个 ID。如果没有 ID,则不会触发事件。

Button imgBtn = new Button();
imgBtn.ID = "imgBtn";

还要确保您添加的每个按钮都有一个唯一的 ID。您可能可以连接楼层编号。或任何其他字段来获得唯一的名称。

此外,除非您在 Page_Load 中对其进行管理,否则该表格将消失。如果 DropDown 具有选定的索引,则需要重新加载表格。

编辑:代码示例

.cs代码

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

protected void cmb_SelectedIndexChanged(object sender, EventArgs e)
{
    PopulateFloorRow();
}

private void PopulateFloorRow()
{
    floorTable.Rows.Clear();

    for (int i = 0; i < 2; i++)
    {
        TableRow tableRow = new TableRow();
        tableRow.Cells.Add(new TableCell());
        tableRow.Cells.Add(new TableCell());

        tableRow.Cells[0].Controls.Add(new Label() { Text = cmb.SelectedItem.Text });
        Button button = new Button();
        button.ID = "btn" + i.ToString();
        button.Text = "Click";
        button.Click += button_Click;
        tableRow.Cells[1].Controls.Add(button);
        floorTable.Rows.Add(tableRow);
    }

}

void button_Click(object sender, EventArgs e)
{
    throw new NotImplementedException();
}

.aspx 代码

<asp:DropDownList id="cmb" runat="server" OnSelectedIndexChanged="cmb_SelectedIndexChanged" AutoPostBack="true"><asp:ListItem>One</asp:ListItem><asp:ListItem>Two</asp:ListItem></asp:DropDownList>
<asp:Table ID="floorTable" runat="server"  Width="100%" GridLines="Both">
</asp:Table>

【讨论】:

  • Praveen,我添加了为每个按钮添加唯一 ID - 仅将模型 ID 添加为按钮 ID,因此它将是唯一的。但是还是不火。我没有明白你想说什么 reg Page_Load,如果 DropDown 选择了索引,我该如何重新加载表格?如果您提供一些示例代码,请您解释一下或更好。
  • Praveen,从我的 SelectedIndexChanged() 中,我调用 private void PopulateFloorRow(int floorNo, FloorPattern fp) 方法。因此,您的意思是,在每次回发时,我都应该检查下拉列表的索引并执行 SelectedIndexChanged() 的整个方法。你觉得这是个好主意吗!他们不应该有更好的选择或方法来达到同样的效果吗!或者这是最好的一个!!!!
  • 一篇文章巧妙地解释了这一点dotnetbull.com/2013/09/…
  • 感谢 Praveen,您的解决方案和共享文章链接确实解决了我的问题。不能有任何其他解决方案可能是客户端。因为,您看到我可能在表中动态添加了 200 多个按钮,然后在每个回发事件中,此过程可能会影响性能。如果我错了,请纠正我。谢谢。
  • 您绝对可以拥有客户端解决方案。我通常使用 Knockout 并进行绑定以呈现模板化控件。你也可以阅读它。如果我的回答解决了您的问题,请不要忘记标记为答案。
猜你喜欢
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 2017-06-06
  • 2022-12-09
  • 2016-04-05
  • 1970-01-01
相关资源
最近更新 更多