Adding multiple custom controls - asp.net

I have a custom control (customContainer) that can hold multiple custom controls of type ConditionControl. When I click a button in my customContainer control I want to add another customControl to my container.
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
CustomControlsPanel.Controls.Add(new LiteralControl("<br />"));
ConditionControl myCc = (ConditionControl)LoadControl(#"~/ConditionControl.ascx");
CustomControlsPanel.Controls.Add(myCc);
}
This works only once. So I click it once, it adds a Condition control but then it does not work anymore. How can I fix this ?
Edit: I tried saving the control collection of my panel into a session variable and then using that in order to restore the controls like so:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Session["controls"] = ConditionControlsPanel.Controls;
}
else
{
ControlCollection temp = (ControlCollection)Session["controls"];
ConditionControlsPanel.Controls.Clear();
foreach (Control ctrl in temp)
{
ConditionControlsPanel.Controls.Add(ctrl);
}
}
}
I get an error when I try to add a new control saying Collection was modified; enumeration operation may not execute. when I try to do the foreach

That is because everytime you click on the button, it postbacks, removes the first one and adds the new one. To overcome this, you can either prevent postback(by something like UpdatePanel) or keep the count of the added ConditionControls (like in session) and add controls as many as the counter you keep in session says

Related

How to update CheckBoxes on the client side after making changes on the server side?

I have a DropDownList and a CheckBox on my web form. After the DropDownList is clicked and this event is posted back to the server. DropDownList_SelectedIndexChanged event is called on the server side. Inside that event handler, I have CheckBox.Checked = true, But I couldn't make the page on the client side to reflect this change (CheckBox.Checked = true). How do I achieve this? Or am I in the wrong direction to use the DropDownList's event handler to update the CheckBox because the page firstly reloads and then DropDownList_SelectedIndexChanged is called?
Page load method:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.DropDownList1.Items.Clear();
AddItemsToDropDownList();
}
}
DropDownList selected index changed event handler:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
var selected = this.DropDownList1.SelectedItem.Text;
CheckBox checkBox = GetCheckBoxToBeSetByText(selected);
checkBox.Checked = true;
}
OK. Found the issue. Actually there is nothing wrong with the code in my original post. But to make a smallest sample when I posted, I removed some "extra" code. The below is the "complete" code (OK, fine, I still removed some code). As you can see, I put the CheckBox into a static Dictionary. Each time the SelectedIndexChanged event handler is called, it's modifying the CheckBox in that static Dictionary, which means it's modifying the CheckBox object created from the last session? (still not clear here) Looks like each time when a postback message is received, a new set of CheckBox objects are created. Bear with me if this is known to everybody here already because I only have two days of experience on this web development thing up to today.
private static Dictionary<Environment, CheckBox> EnvironmentsCheckBoxes;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
EnvironmentsCheckBoxes = new Dictionary<Environment,CheckBox>();
EnvironmentsCheckBoxes.Add(Environment.Dev1, this.Dev1_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.Dev2, this.Dev2_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.QA, this.QA_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.QA2, this.QA2_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.Demo, this.Demo_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.Prod, this.Prod_CheckBox);
EnvironmentsCheckBoxes.Add(Environment.UAT, this.UAT_CheckBox);
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
var selected = this.DropDownList1.SelectedItem.Text;
if (selected == "Dev1")
{
EnvironmentsCheckBoxes[Environment.Dev1].Checked = true;
}
else if (selected == "Dev2")
{
...
}
...
}

how to disable a pageload property under certain circumstances

In .NET i have a gridview which has to display on the mainpage with default settings. So i put it in pageload code. In the same page i have a "List" button; people choose date etc. and when they press the button gridview loads data from another stored procedure. I put that code under List button event. But after people press List button and gridview comes with the needed data, if they press something else (because of page refresh itself) gridview turns back to default settings.
How do i keep the gridview with wanted data?
protected void Page_Load(object sender, EventArgs e)
{
opsbelgegridview.DataSource = DB.OpsHavuzGetir();
opsbelgegridview.DataBind();
protected void listelebtn_Click(object sender, EventArgs e)
{
opsbelgegridview.DataSource = DB.OpsHavuzDetayListeleBtn(tarih1.ToString("yyyy-MM-dd"), tarih2.ToString("yyyy-MM-dd"), durumdd.SelectedItem.Text.ToString(), islemtipdd.SelectedItem.Text.ToString());
opsbelgegridview.DataBind();
You can use IsPostBack() and only load the initial grid on the first load of the page. Then if the grid data changes it will stay.
private void Page_Load()
{
if (!IsPostBack)
{
opsbelgegridview.DataSource = DB.OpsHavuzGetir();
opsbelgegridview.DataBind();
}
}

Select all items in listbox when updated via UpdatePanel

protected void Page_Load(object sender, EventArgs e)
{
if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
{
string id = ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID;
if (id == cboGroup.UniqueID)
{
foreach (ListItem i in lstTest.Items)
i.Selected = true;
}
}
}
This code runs when my cboGroup causes my UpdatePanel to refresh which has the lstTest in it and the data inside of it gets updated, but it does NOT select them all. How can I make it so when my UpdatePanel is finished refreshing all elements of the list box that it refreshed get selected?
[edit] I'm noticing now that at this point what's in the listbox is the previous values and not the new values I would need. So this seems to be before the listbox is filled with data (which is via a SqlDataSource) so it's probably overwriting this.
I was able to put my selection code in the list box's DataBound() event.
protected void lstTest_DataBound(object sender, EventArgs e)
{
SelectAllTest();
}

On postback htmlgeneric control remove its childeren controls in asp.net, why?

I have an htmlgeneric control and on run time i am adding control in it but when i click on any button then added controls disappear.
Dynamically created controls need to be created on every post back. You also need to give them an ID if you want to maintain and restore their ViewState.
For example, this will show the TextBox the first time the page is loaded, but on any subsiquent page loads, the control will be missing:
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
TextBox newControl = new TextBox()
{
ID = "newControl"
};
SomeControl.Controls.Add(newControl);
}
}
However, if you create the control on every postback with the same Id, then the control will be maintained with it's Text:
protected void Page_Init(object sender, EventArgs e)
{
TextBox newControl = new TextBox()
{
ID = "newControl"
};
SomeControl.Controls.Add(newControl);
}
Here's a good article about dealing with dynamic controls.

Handle Button Click Event from User Control loaded dynamically

I have a blank user control (child) and during Page_Load i create some text boxes and a button. I also add an event to the button.
I then load that user control dynamically from a placeholder in another usercontrol (parent).
Both controls are rendered correctly but when i click on the button, the event isnt fired.
Any ideas on how to handle the event?
Child code:
protected void Page_Load(object sender, EventArgs e)
{
/*... other user controls ..*/
UpdateButton = new LinkButton();
UpdateButton.ID = "buttonid";
UpdateButton.Text = "text";
UpdateButton.Click += new EventHandler(UpdateButton_Click);
this.Controls.Add(UpdateButton);
}
protected override void Render(HtmlTextWriter writer)
{
for (int i = 0; i < this.Controls.Count; i++)
{
this.Controls[i].RenderControl(writer);
}
}
public void UpdateButton_Click(object sender, EventArgs e)
{
//Do stuff
}
Parent code:
protected void Page_Load(object sender, EventArgs e)
{
placeholder.Controls.Clear();
ChildControl uc = (ChildControl)LoadControl("~/UserControls/ChildControl.ascx");
placeholder.Controls.Add(uc);
}
If i use the child control directy (ie without the parent the control) the click event is raised and handled nicely. But when i use the parent control, the debugger wont even hit a breakpoint inside UpdateButton_Click().
Thanks in advance.
I think I know what might be happening. In your parent Page_Load you are calling placeholder.Controls.Clear(); This does what you would imagine and clears the control, including any events that have occurred. What happens when remove this line? Do you get an additional one created on each postback?

Resources