0

我想根据用户选择的 DropDownList 选择在运行时动态地将用户控件添加到页面中的 PlaceHolder。像这样的东西:

protected void Page_Init(object sender, EventArgs e)
{
    //get user's content selection
    int contentMode;

    if (!IsPostBack)
        contentMode = 1;
    else
        contentMode = Int32.Parse(Request.Form[ddlMode.UniqueID]);

    //load a user control
    ContentControl ucContent = null;

    switch (contentMode)
    {
        case 1:
            ucContent = LoadControl("~/Controls/SomeContent1.ascx") as ContentControl;
            break;
        case 2:
            ucContent = LoadControl("~/Controls/SomeContent2.ascx") as ContentControl;
            break;
    }

    ucContent.ID = "ucContent"; 

    phContentArea.Controls.Add(ucContent);
}

...这几乎可以工作,但在两次回发后我得到了这个:

无法加载视图状态。正在加载视图状态的控制树必须与在先前请求期间用于保存视图状态的控制树匹配。例如,当动态添加控件时,回发期间添加的控件必须与初始请求期间添加的控件的类型和位置相匹配。

...我读到的原因是第二次回发的控件与之前的回发不同。我试图通过为控件提供相同的 ID 和类型来防止这种情况,但没有骰子。两个控件:

public partial class SomeContent1 : Foo.Bases.ContentControl
{
    //code
}

public partial class SomeContent2 : Foo.Bases.ContentControl
{
    //code
}

我是否缺少使这项工作起作用的难题的一部分?我读过类似的问题,但建议没有成效。

谢谢

4

2 回答 2

0

在 init 事件中,您必须确保控件树与回发的前一个控件树匹配;因此,如果您删除控件,则需要在 init 运行后将其删除,也就是加载视图状态时。

此外,可能需要在 PreInit 中完成初始加载,您可以尝试看看这是否也有帮助。

于 2014-11-03T22:41:58.933 回答
0

另一种有效但与我的问题不同的技术是在运行时添加所有内容控件,但将未选择的内容控件的可见性设置为 False:

switch (contentMode)
{
    case 1:
        ucContent = LoadControl("~/Controls/SomeContent1.ascx") as ContentControl;
        phContentArea.Controls.Add(ucContent);

        ucContent = LoadControl("~/Controls/SomeContent2.ascx") as ContentControl;
        ucContent.Visible = false;
        ucContent.EnableViewState = false;
        phContentArea.Controls.Add(ucContent);    
        break;

    case 2:
        ucContent = LoadControl("~/Controls/SomeContent1.ascx") as ContentControl;
        ucContent.Visible = false;
        ucContent.EnableViewState = false;
        phContentArea.Controls.Add(ucContent);

        ucContent = LoadControl("~/Controls/SomeContent2.ascx") as ContentControl;
        phContentArea.Controls.Add(ucContent);
        break;
}

...但这感觉不如仅加载所需的控件。

于 2014-11-03T23:17:44.047 回答