3

这是我的代码:

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.NullReferenceExceptionif (MesiSelezionati.Contains(hf.ID.Split('_').LastOrDefault()))

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

编辑:马克 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);
4

2 回答 2

3

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

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

  1. InnerHtml = "mese"在 OnInit 方法中设置锚标记 ( ) 的 InnerHtml 属性。在幕后,这项任务是ViewState["innerhtml"] = "mese"
  2. 在 ViewState 跟踪开始后,您将 css 类分配给锚点,因此 ViewState 恢复机制将在回发时应用于此控件。

当您回发带有添加的 css 类的锚标记时,将受制于 HtmlContainerControl.LoadViewState(发生在 InitComplete 和 PreLoad 之间)。如果 LoadViewState 方法检测到 ViewState["innerhtml"] 有一个值,它会清除控件的所有子控件(调用 Controls.Clear())并创建一个 LiteralControl 来包含 innerhtml 值,并将其添加为唯一的子控件。

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

修正你的榜样;而不是设置 InnerHtml 来添加链接文本,而是使用所需的文本创建一个 LiteralControl 并将其添加到锚的子控件集合中。

于 2012-05-15T14:50:22.113 回答
0

您的链接按钮在某个单独的面板控件中吗?是否可以使用 AJAX 进行部分回发?很抱歉回答这个问题。

于 2012-05-15T17:40:13.377 回答