Dynamic Placeholder Control and attaching an Event - c#

I have been getting some massive head aches working on a very dynamic app.
I am using a dynamic placeholder control from:
http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx
This saves me a lot of hassle when trying to re-create dynamically created controls after a postback.
Has anyone else had any issues with attaching a event handler to checkbox control?
Here is my code for the dynamically created checkbox.
// Now I create my checkbox
chkDynamic = new CheckBox();
string chk = "chk";
// Add it to our dynamic control
chkDynamic.CheckedChanged += new EventHandler(chkDynamic_CheckedChanged);
chkDynamic.ID = chk;
DynamicControlsPlaceholder1.Controls.Add(chkDynamic);
chkDynamic.Text = "hey";
This works, but its like the event is not getting attached!
Here is my event handler!
protected void chkDynamic_CheckedChanged(object sender, EventArgs e)
{
if (((CheckBox)sender).Checked)
Response.Write("you checked the checkbox :" + this.chkDynamic.ID);
else
Response.Write("checkbox is not checked");
}
Now if I was to use a regular placeholder or a panel this works great.
Ex. Change this line:
DynamicControlsPlaceholder1.Controls.Add(chkDynamic);
to
Panel1.Controls.Add(chkDynamic);
And it works perfect.
Could someone please tell me, is this an issue with this control, or my coding?
There are no errors, the only thing that is happening that is unexpected is my event is not firing when I'm using the DynamicControlsPlaceholder.

Creating a delegate (anonymous method) did the job for me.
// Now I create my checkbox
chkDynamic = new CheckBox();
string chk = "chk";
// Add it to our dynamic control
chkDynamic.CheckedChanged += delegate (System.Object o, System.EventArgs e)
{
if (((CheckBox)sender).Checked)
Response.Write("you checked the checkbox :" + this.chkDynamic.ID);
else
Response.Write("checkbox is not checked");
};
chkDynamic.ID = chk;
DynamicControlsPlaceholder1.Controls.Add(chkDynamic);
chkDynamic.Text = "hey";
this will cause the code written in delegate to execute whenever dynamic control hits the action "CheckedChanged"

If you are adding dynamic controls, you MUST create/recreate the controls no later than OnInit(). This is the point in the .NET page lifecycle where the viewstate and events are restored. If it is solely for the purpose of adding dynamic controls that you are using the dynamic placeholder control, then simply putting the control creation/recreation in OnInit() will solve your problem. Give it a try and let me know your results.

Ok, so this works with one dynamically created control. But not with multiple...

Related

Deleteing a panel after checkbox checked

I have a code that generates multiple panels, each including some labels and comboboxes. One of the controls included in each panel is a checkbox, what I need to do is, that when user checks the checkbox, the whole panel where the checkbox was will be deleted.
Inside a foreach loop that generates the panels, the panel itself can be reached with name "Strip". Outside this loop, if I would transfer all necessary parameters(or arguments, not sure about the terminology here), it would be called after one of its labels "callsign", so when I need to get its name out into a method, I set as a parameter "callsign.Text".
Now, here is my Checbox generating code:
CheckBox check = new CheckBox();
check.Location = new Point(270, 10);
check.Name = "check:" + callsign.Text;
check.CheckedChanged += new System.EventHandler(CheckCheckedChanged(callsign.Text));
Strip.Controls.Add(check);
and here is definition of method CheckCheckedChanged:
public void CheckCheckedChanged(string callsign, object sender, EventArgs e)
{
}
... First of all, I get en error at line check.CheckedChanged += new System.EventHandler(CheckCheckedChanged(callsign.Text));
It says, that "No overload for method CheckCheckedChanged takes 1 arguments". I dont know whats wrong, so thats my first question. The second is - I cant figure out how to write the method to delete the one specific panel named after the callsign.Text, if I would write just "callsign dispose" then I guess it wouldnt work.
Thanks in advance
The first thing you need to do is remove the string callsign parameter from your event handler. That is what's causing the compiler error. So your method signature will look like this:
public void CheckCheckedChanged(object sender, EventArgs e)
Secondly, you need to change how the event is attached to event handler:
check.CheckedChanged += new System.EventHandler(CheckCheckedChanged(callsign.Text));
will become:
check.CheckedChanged += new System.EventHandler(CheckCheckedChanged);
Next, you want to put code into the event handler to get the state of the checkbox and set the visibility of the panel accordingly. You will replace the panel with the name of your panel.
public void CheckCheckedChanged(object sender, EventArgs e)
{
CheckBox checkbox = sender as CheckBox;
if (checkbox != null)
{
((Panel)checkbox.Parent).Visible = !checkbox.Checked; // replace this with your panel
}
}

Groupbox check for changes event

I have a DataGridView and a GroupBox control containing a few ComboBoxes.
Depending on what is selected in the ComboBoxes, the elements in the grid changes.
Is there a way to say
If (Something Changes Within The GroupBox)
{
//Update the grid
}
(Without writing a OnSelectedIndexChange event for every boxes)
I don't want the code for the updating part, I just need an event or something I could use to check if a the value of a control has changed within the GroupBox.
Any Idea ?
Update
Ok I think I didn't explained it the right way.
Forget about the ComboBox.
Let's say I have a bunch of controls in a GroupBox is there a way to say :
As soon as the value of one of the control changes, create an event.
You could hook up each combo box SelectedIndexChanged event to one method:
comboBox1.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange);
comboBox2.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange);
comboBox3.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange);
comboBox4.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange);
Or using LINQ to setup an event handler for any combo box selection change:
GroupBox.Controls.OfType<ComboBox>.ForEach(cb => cb.SelectedIndexChanged += new System.EventHandler(GroupBoxComboBoxChange));
Answer to your update: You are looking for a ControlValueChanged() event. I think the problem here is that all controls are different. What defines a "ValueChanged" event for a ComboBox isn't necessarily the same for a TextBox. It would be a semantic challenge and not very clear. Hope this makes sense.
There is no "something inside me changed" for GroupBoxes, but you can "cheat" and DYI like this (it's just a proof-of-concept without error checking and the sort):
// In a new Windows Forms Application, drop a GroupBox with a ComboBox and a CheckBox inside
// Then drop a TextBox outside the ComboBox. Then copy-paste.
// this goes somewhere in your project
public static class handlerClass
{
public static string ControlChanged(Control whatChanged)
{
return whatChanged.Name;
}
}
// And then you go like this in the Load event of the GroupBox container
void Form1_Load(object sender, EventArgs args)
{
foreach (Control c in groupBox1.Controls)
{
if (c is ComboBox)
(c as ComboBox).SelectedValueChanged += (s, e) => { textBox1.Text = handlerClass.Handle(c); };
if (c is CheckBox)
(c as CheckBox).CheckedChanged += (s, e) => { textBox1.Text = handlerClass.Handle(c); }; }
}
}
Since every Control has its own "I'm changed!" kind of event, I don't think it can be any shorter as far as boilerplate goes. Behavior is a mere sample that writes the name of the control that changed in a ComboBox
GroupBoxes are usually just decorative unless they are managing radio buttons or check boxes, so expecting them to be aware of changes made to combo boxes is not something easily done out of the box. If I may, why not code a method that does what you want it to do, and then call that method from all your combo boxes' SelectedIndexChanged events?

Checkbox Changed Event not firing for dynamically added control

I have created a 3 checkboxes in my jQuery accordion control dynamically in the page load event and I am also associating the CheckedChanged Event for the textbox. But the event is not firing at all. I am not sure what is happening here. Please help me. Thanks and appreciate your feedback.
Code that I used to generate dynamic control and associate the event
protected void Page_Load(object sender, EventArgs e)
{
dvAccordion.Controls.Clear();
foreach (DataRow row in dataSetIP.Tables[0].Rows)
{
HtmlGenericControl tt= new HtmlGenericControl("H3");
HtmlAnchor anc= new HtmlAnchor();
HtmlGenericControl dvP= new HtmlGenericControl("DIV");
dvP.InnerHtml = row["LD"].ToString();
CheckBox chkTest = new CheckBox();
if (!Page.IsPostBack) chkTest .ID = "chk" + row["SD"].ToString();
else
{
string uniqueID = System.Guid.NewGuid().ToString().Substring(0, 5);
chkTest .ID = "chk" + uniqueID + row["SD"].ToString();
}
chkTest.Text = row["SD"].ToString();
chkTest.AutoPostBack = true;
chkTest.CheckedChanged += new EventHandler(chkTest _CheckedChanged);
chkTest.InputAttributes.Add("Value", row["ID"].ToString());
anc.Controls.Add(chkTest);
tt.Controls.Add(anc);
dvAccordion.Controls.Add(tt);
dvAccordion.Controls.Add(dvP);
}
}
But the CheckboxChanged event is not firing.
It's an issue of when you add the control, ViewState, and some of the lifecycle. Dynamically adding controls that fully participate in the whole lifecycle is a complicated subject, and without more context, it's best for you to read the Truly Understanding Dynamic Controls series.
In your case, I think you're re-creating the control on the next page load after the ViewState initialization, so it doesn't know about the binding at the time it needs to queue up the call to your bound event handler.
Try adding the controls in the Page_Init() event (which is fired before the Page_Load() event).

How to call an event handler from one control to the another control where the second control is inside the first control?

i have a calender control like this
<asp:Calendar ID="CldrDemo" runat="server" BackColor="#FFFFCC" BorderColor="#FFCC66"
OnSelectionChanged="CldrDemo_SelectionChanged" OnDayRender="CldrDemo_DayRender">
</asp:Calendar>
OnDayRender event i have code like this
protected void CldrDemo_DayRender(object sender, DayRenderEventArgs e)
{if (e.Day.Date == Convert.ToDateTime("11/30/2010"))//comparing date
{
DropDownList ddlBlist = new DropDownList();//creating instance of ddl
ddlBlist.AutoPostBack = true;
ddlBlist.Items.Add("Ashrith");//adding values to the ddl
ddlBlist.Items.Add("Nayeem");//adding values to the ddl
ddlBlist.SelectedIndexChanged += new EventHandler(ddlBlist_SelectedIndexChanged);//want to call this
string name = ddlBlist.SelectedItem.Text;
e.Cell.Controls.Add(ddlBlist);//adding dropdownlist to the cell
e.Cell.BorderColor = System.Drawing.Color.Black;
e.Cell.BorderWidth = 1;
e.Cell.BackColor = System.Drawing.Color.LightGray;
}
i want to call the event handler for the dropdownlist - selectedIndexchanged and i have added it also like this
protected void ddlBlist_SelectedIndexChanged(object sender, EventArgs e)
{
}
but this is not getting fire when i am changing the item of the dropdownlist. Please help
try this
ddlBlist.SelectedIndexChanged += new EventHandler("ddlBlist_SelectedIndexChanged");
try putting your calendar control in a Ajax update panel
and put this line before adding items in your combo box:
ddlBlist.SelectedIndexChanged += new EventHandler(ddlBlist_SelectedIndexChanged);
ddlBlist.Items.Add("Ashrith");//adding values to the ddl
ddlBlist.Items.Add("Nayeem");//adding values to the ddl
I believe in order to get this to work you need to have re-added your drop-down list to the controls collection before the SelectedIndexChanged event would normally be fired.
What's happening is, you're adding your control dynamically at render time, but when a post-back happens the control doesn't actually exist any more, or at least it won't until your render method gets called again. And so the event will not fire.
In my experience with adding controls dynamically like this, in order to be able to handle any events they raise you need to be able to re-create your dynamic control tree before the page's Load event occurs. If you can do this, you will probably find that your event will fire as normal.

How and WHEN to save the values of the "Checked" attribute for Dynamic checkboxes

I am adding some checkboxes dynamically during runtime, and I need to know whether they are checked or not when I reload them next time.
I load the checkbox values from a list stored in ViewState.
The question is: when do I save or check for the value of the the Checked?
I tried the event dispose for the check box and the place holder I am adding the checkboxes in, but it wasn't fired. i.e. when I put a break point it didn't stop. So any suggestions?
This is a sample code, but I don't think it is necessary:
void LoadKeywords()
{
bool add = true;
foreach (string s in (ViewState["keywords"] as List<string>))
if (s == ddlKeywords.SelectedItem.Text)
{
add = false;
continue;
}
if (add)
(ViewState["keywords"] as List<string>).Add(ddlKeywords.SelectedItem.Text);
foreach (string s in (ViewState["keywords"] as List<string>))
{
CheckBox kw = new CheckBox();
kw.Disposed += new EventHandler(kw_Disposed);
kw.Text = s;
PlaceHolderKeywords.Controls.Add(kw);
}
}
If you are dynamically adding controls at run time you have to make sure that those controls are populated to the page's Control collection before ViewState is loaded. This is so that the state of each checkbox can be rehydrated from Viewstate. The Page Load event, for example, is too late.
Typically you would dynamically add your CheckBox controls during the Init Event (before view state is loaded) and then Read the values in your Checkbox controls during the Load event (after view state is loaded).
eg:
protected override void OnInit(EventArgs e)
{
//load the controls before ViewState is loaded
base.OnInit(e);
for (int i = 0; i < 3; i++)
{
CheckBox cb = new CheckBox();
cb = new CheckBox();
cb.ID = "KeyWord" + i.ToString();
cb.Text = "Key Word"
MyPlaceHolder.Controls.Add(new CheckBox());
}
}
//this could also be a button click event perhaps?
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (Page.IsPostBack)
{
//read the checkbox values
foreach(CheckBox control in MyPlaceHolder.Controls)
{
bool isChecked = control.Checked;
string keyword = control.Text;
//do something with these two values
}
}
}
Hope that helps
****EDIT****
Forgot to mention that this is obviously just demo code - you would need to flesh it out.
For more information on dynaic control rendering in ASP.Net check out this article on 4Guys.
For more information on the page life-cycle in ASP.Net check out MSDN.
How to:
try adding a javascript code, that handles checked(),
u can get the checkboxes by using document.findElementById(ID) , then store the checkboxe's value into a hiddenfield that has a runat="server" property.
When to:
either on pageload , check if page is postback(), and check the hiddenfield(s) value(S). or add a submit button (and place its event in the code behind, runat="server" property).
hope this helps u.

Categories

Resources