ASP.NET 基于 ViewState 中的值加载动态控件

ASP.NET Loading dynamic controls based on value in ViewState

提问人:martin36 提问时间:9/5/2018 更新时间:9/5/2018 访问量:313

问:

我一直在寻找解决这个问题的方法,但我还没有找到。

问题来了, 我有一个静态创建的表,其中包含一个列表,而不是其他列表:

<table class="styled-list">
    <tbody>
        <tr>
            <td><a>Lista 1</a></td>
            <td>
                <asp:Button runat="server" ID="btnDelete1" />
                <asp:Button runat="server" ID="btnEdit1" />
            </td>
        </tr>
        <tr>
            <td><a>Lista 2</a></td>
            <td>
                <asp:Button runat="server" ID="btnDelete2" />
                <asp:Button runat="server" ID="btnEdit2" />
            </td>
        </tr>
    </tbody>
</table>

单击这些列表中任何一个的编辑按钮时,应显示另一个列表。为了知道选择了哪个列表,我将列表的名称保存在 中。ViewState

private string ListNameOfSelected
{
    get
    {
        if (ViewState["ListNameOfSelected"] != null) return (string)ViewState["ListNameOfSelected"];
        else return "";
    }
    set { ViewState["ListNameOfSelected"] = value; }
}


protected void btnEdit_Click(object sender, EventArgs e, string name)
{
    ListNameOfSelected = name;
    RenderPersonsInList();
}

该函数将创建一个列表,其中包含所选列表中的人员。RenderPersonsInList()

private void RenderPersonsInList()
{
    txtNameInTitle.InnerText = ListNameOfSelected;
    TableRow tr;
    TableCell nameCell, emailCell, deleteCell;
    ImageButton deleteButton;
    Guid[] ids = new Guid[] { };
    string[] names = new string[] { };
    string[] emails = new string[] { };

    switch (ListNameOfSelected)
    {
        case "Lista 1":
            ids = new Guid[] { Guid.NewGuid(), Guid.NewGuid() };
            names = new string[] { "Anonymous1", "Anonymous2" };
            emails = new string[] { "[email protected]", "[email protected]" };
            break;
        case "Lista 2":
            ids = new Guid[] { Guid.NewGuid() };
            names = new string[] { "Anonymous3" };
            emails = new string[] { "[email protected]" };
            break;
        default:
            break;
    }


    for (int i = 0; i < names.Length; i++)
    {
        Guid personID = ids[i];
        tr = new TableRow
        {
            ID = "row-" + personID.ToString()
        };
        nameCell = new TableCell
        {
            Text = names[i]
        };
        emailCell = new TableCell
        {
            Text = emails[i]
        };
        deleteCell = new TableCell();
        deleteButton = new Button
        {
            ID = personID.ToString()
        };
        deleteButton.Click += (sender, EventArgs) => { DeleteButton_Click(sender, EventArgs, names[i], personID); };
        deleteCell.Controls.Add(deleteButton);
        tr.Controls.Add(nameCell);
        tr.Controls.Add(emailCell);
        tr.Controls.Add(deleteCell);
        tbListMembers.Controls.Add(tr);
    }
    pnlViewList.Visible = true;

}

现在的问题是,当用户在动态创建的列表中单击时,会出现回发,需要重新创建列表。但是,为了使单击侦听器正常工作,必须在 or 函数中创建列表,而此处尚未启动。deleteButtonPage_InitPage_PreInitViewState

有没有办法知道用户在创建动态列表时选择了哪个列表,无论是使用还是其他方式?ViewState

谢谢

C# asp.net ViewState ClickListener aspButton

评论

0赞 VDWWD 9/5/2018
您无需Page_Init或Page_PreInit即可创建动态控件。Page_Load工作很好。
0赞 martin36 9/5/2018
如果我在 Page_Load 中创建控件,则单击侦听器不起作用
0赞 VDWWD 9/5/2018
是的,他们可以。请在此处查看我的答案以获取简单的演示。您会看到未使用 Init 或 PreInit。
0赞 martin36 9/5/2018
我尝试在Page_Load中移动用于创建列表的代码,但随后点击侦听器不会触发

答:

1赞 Brian Cryer 9/5/2018 #1

你快到了。解决方案是不使用 ViewState。这是因为(正如您已经确定的)ViewState 值在 PageInit 中不可用,但您需要该值,这是您遇到的问题。

请改用隐藏值 - HiddenField 控件即可。当然,在 PageInit 期间,控件也不会加载其值。因此,要获取值,请使用 Page.Request.Params[MyHiddenField.UniqueID]

评论

0赞 martin36 9/5/2018
非常感谢你,我从来没有想过这一点。