This is my code :
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");
}
}
}
When I call the page, all is ok! The problem is when I call the same page (so, postback) thanks to a asp:LinkButton. I get a System.NullReferenceException on if (MesiSelezionati.Contains(hf.ID.Split('_').LastOrDefault())).
Seems that the HiddenField of the 2° and 4° link (which corrispond to the position at MesiSelezionati = new string[] { "2", "4" };) are null. Why? And how can I fix it?
EDIT : code for Mark M
HtmlGenericControl optionBox = new HtmlGenericControl("div");
optionBox.Attributes["class"] = "option-box";
HtmlGenericControl optionBoxItem = new HtmlGenericControl("a") { InnerHtml = " " };
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);
You can update hidden fields on postback, just not before Load. When executing OnInit, the controls have not been populated using the request & view state values. Your updates are being overwritten.
EDIT: I found the root cause of your issue & learned something in the process.
InnerHtml = "mese") in the OnInit method. Under the covers this assignment isViewState["innerhtml"] = "mese".When you postback the anchor tags with added css classes will be subject to HtmlContainerControl.LoadViewState (which occurs between InitComplete and PreLoad). If the LoadViewState method detects that ViewState[“innerhtml”] has a value it wipes out all of the control’s child controls (calling Controls.Clear()) and creates a LiteralControl to contain the innerhtml value, adding it as the sole child control.
Basically this means that you cannot set both the InnerHtml property and add any controls to a descendant of HtmlContainerControl if that control will ever be subject to ViewState tracking.
To fix your example; instead of setting InnerHtml to add the link text, create a LiteralControl with the desired text and add it to the anchor’s child control collection.