这是我的代码:

private string[] MesiSelezionati;

protected void Page_Load(object sender, EventArgs e)
{
    MesiSelezionati = new string[] { "2", "4" };
    UpdateMesi();
}

override protected void OnInit(EventArgs e)
{
    for (int i = 1; i <= 12; i++)
    {
        HtmlGenericControl meseItem = new HtmlGenericControl("a") { InnerHtml = "mese" };
        meseItem.Attributes.Add("href", "javascript:void(0);");

        HiddenField hf = new HiddenField();
        hf.Value = "0";
        hf.ID = "idMese_" + i.ToString();

        meseItem.Controls.Add(hf);

        panelMesi.Controls.Add(meseItem);
    }

    base.OnInit(e);
}

private void UpdateMesi()
{
    foreach (HtmlGenericControl a in panelMesi.Controls.OfType<HtmlGenericControl>())
    {
        HiddenField hf = a.Controls.OfType<HiddenField>().LastOrDefault();
        if (MesiSelezionati.Contains(hf.ID.Split('_').LastOrDefault()))
        {
            hf.Value = "1";
            a.Attributes.Add("class", "box-ricerca-avanzata-item link-box selected");
        }
    }
}


当我呼叫该页面时,一切正常!问题是当我通过asp:LinkBut​​ton调用同一页面(即回发)时。我在System.NullReferenceException上得到一个if (MesiSelezionati.Contains(hf.ID.Split('_').LastOrDefault()))

似乎2°和4°链接的HiddenField(与MesiSelezionati = new string[] { "2", "4" };的位置相对应)为空。为什么?我该如何解决?

编辑:Mark M的代码

HtmlGenericControl optionBox = new HtmlGenericControl("div");
optionBox.Attributes["class"] = "option-box";

HtmlGenericControl optionBoxItem = new HtmlGenericControl("a") { InnerHtml = "&nbsp;" };
optionBoxItem.Attributes.Add("href", "javascript:void(0);");
optionBoxItem.Attributes.Add("class", "option-box-item");

HtmlGenericControl optionBoxTesto = new HtmlGenericControl("a") { InnerText = Categoria.Categoria };
optionBoxTesto.Attributes.Add("href", "javascript:void(0);");
optionBoxTesto.Attributes.Add("class", "option-box-testo");

HiddenField hf = new HiddenField();
hf.Value = "0";
hf.ID = "categoria_" + Categoria.UniqueID;

optionBox.Controls.Add(optionBoxItem);
optionBox.Controls.Add(optionBoxTesto);
optionBox.Controls.Add(hf);

panelCategorieGuida.Controls.Add(optionBox);

最佳答案

您可以在回发时更新隐藏字段,而不是在加载之前。执行OnInit时,尚未使用请求和视图状态值填充控件。您的更新已被覆盖。

编辑:我找到了您问题的根本原因,并在此过程中学到了一些东西。


您可以在OnInit方法中设置锚标记(InnerHtml = "mese")的InnerHtml属性。在封面下,此任务为ViewState["innerhtml"] = "mese"
在开始对ViewState进行跟踪之后,可以将css类分配给锚,因此ViewState恢复机制将在回发时应用于此控件。


当您回发添加了CSS类的锚标记时,将遵循HtmlContainerControl.LoadViewState(在InitComplete和PreLoad之间发生)。如果LoadViewState方法检测到ViewState [“ innerhtml”]具有一个值,它将擦除该控件的所有子控件(调用Controls.Clear()),并创建一个LiteralControl来包含innerhtml值,并将其添加为唯一的子控件。

基本上,这意味着您无法同时设置InnerHtml属性和将任何控件添加到HtmlContainerControl的后代,如果该控件将受到ViewState跟踪。

修正你的例子;与其设置InnerHtml添加链接文本,不如创建具有所需文本的LiteralControl并将其添加到锚点的子控件集合中。

关于c# - 为什么我不能在PostBack上更新HiddenFields?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10603185/

10-15 05:47