I have a web form which dynamically loads controls upon selection in combobox(devexpress). I have the following code on main form
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
if (Session["_active_control"] != null)//persist control on postbacks
{
Control cntrl = Session["_active_control"] as Control;
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
}
}
protected void cmb_control_SelectedIndexChanged(object sender, EventArgs e)
{
Control cntrl= Page.LoadControl("~/" + cmb_control.SelectedItem.Value);
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
Session["_active_control"] = cntrl;
}
also I have a user control having three Textboxes and a button having code
protected void btn_save_Click(object sender, EventArgs e)
{
lbl.Text = ASPxTextBox1.Text + "<br>" + ASPxTextBox2.Text + "<br>" + ASPxTextBox3.Text;
}
My problem is that the save button of user control is not firing if i load it dynamically (I have checked using breakpoints and also the code shown above. however it runs smoothly if I use it statically.(i.e. by dragging in design mode)
You are right that you have to persist the control across postbacks.
However the Page Load event is too late to add back your controls. Do this on the Init event of your page and you should be good. To receive a postback event, the control should be present when ProcessPostData(called before PreLoad) is called.
Also for textboxes you will want to receive the values entered by the user. This too happens on ProcessPostData, if you add you control after that, you will not receive the values entered by the user.
Refer: ASP.NET Page Life Cycle
hey i found the solution
instead on creating the controls in combobox_selectedindexchanged i put my control creation code on Pageload based in combobox.selectedindex i.e.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (cmb_control.SelectedItem != null)
{
Control cntrl = Page.LoadControl("~/" + cmb_control.SelectedItem.Value);
cntrl.ID = "_new_ctrl" + cmb_control.SelectedItem.Value;
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
}
}
see Button click event not firing within use control in ASP .Net
Related
I have a web user control in asp.net - a keypad. It has buttons for all digits, a textbox for display of input and clear and submit buttons. The user control sits in AJAX update panel so it can be easily shown/hidden. (App is destined for tablet browsers) I need to add a delegate to subMitButton ClickEventHandler inside my user control inside AJAX update panel. Any suggestions? Is it even possible? I don't want to use tablet's soft numeric keyboard because it is way to big. I could break my user control apart and use its code inside my web site but I'd rather use user control as intended.
you can raise an event from usercontrol which can be handled in the page .
You can declare a event
public event EventHandler SubmitButtonClick;
protected void OnSubmitButtonClick()
{
if (SubmitButtonClick!= null)
{
SubmitButtonClick(this, new EventArgs());
}
}
And then on the page, handle the event .
WebUserControl1.SubmitButtonClick+=
new WebUserControl.EventHandler(WebUserControl1_SubmitButtonClick);
private void WebUserControl1_SubmitButtonClick(object sender, EventArgs e)
{
Label1.Text = "Button Pressed";
}
Because of the ASP.NET webpage lifecycle I get Nulls when I set public properties on the user control from the main page. Those variables go out of scope once the page is sent to the client. However, here is an easy solution that will let you get notified when an event happens in your user control.
NOTE: There are some issues with Page.Context when back in the main page so changing things that effect the viewstate might not work.
Inside my user control i did the following...
// UC - setting up delegate and usercontrol property to store it
public delegate void CallbackAction(object sender, CustomEventArgs e);
public CallbackAction OnCallbackAction
{
get { return Session["CallbackAction"] as CallbackAction; }
set { Session["CallbackAction"] = value; }
}
Somewhere in the UserControl an event happens that you want to notify the main page of
// UC - callback from within the usercontrol
protected void UserControlButton_Click(object sender, EventArgs e)
{
if (IsPostback)
{
// do some processing
if (this.OnCallbackAction != null)
{
this.OnCallbackAction.Invoke(this, new CustomEventArgs("ET phone home") );
}
}
}
The structure above will now callback a main page that registers with the usercontrol. Here is how to register with the usercontrol from the main page
// Main Page - load event
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostback)
{
// register with usercontrol
this.UserControlFoo.OnCallbackAction += CallbackFromUserControl_Click;
}
}
// Main Page - this event will get called back when ET phones home
protected void CallbackFromUserControl_Click(object sender, CustomEventArgs e)
{
// phoned home from usercontrol
}
i have a problem with user control.
i create it dynamically on my aspx page after clicking on a button:
protected void btnAddRules_Click(object sender, EventArgs e)
{
RuleProperty Control = (RuleProperty)LoadControl("RuleProperty.ascx");
MyPanel.Controls.Add(Control);
}
when i click on a button of my user control, the button event wont fire and the user control will disappear. here is the button event:
protected void btnAdd_Click1(object sender, EventArgs e)
{
WowzaRule rule = GetRuleFromGUI();
RuleList.Add(rule);
//Session["RuleList"] = RuleList;
//List<WowzaRule> test = new List<WowzaRule>();
SaveToXMLFiles(txtdbnum.Text, RuleList);
}
i understand that after pressing the button on mypage the usercontrol is released and if its not created on pag_init or page Load it wont stay, but i need to create it on my button click event and find a way for it not to disapper.
thanks in advance, Daniel
You might have to add an event handler that it can fire the click event and call your delegate
Control.Click += btnAdd_Click1;
Dynamically created controls, once added, have to be on a page on every page load in order to work correctly. What happens in your case:
RuleProperty is added after the button click
Page loads with this control
User clicks on the button within RuleProperty
Control is not added to the control tree during the page load (corresponding code is only in the button click handler, and that button was not clicked)
ASP.NET does not know which control triggered the event, so the event is not processed
To go around this issue you need to add you control on every page loading, for example using some flag stored in ViewState:
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["AddRuleProperty"] != null && (bool)ViewState["AddRuleProperty"])
{
AddRulePropertyControl();
}
}
protected void btnAddRules_Click(object sender, EventArgs e)
{
AddRulePropertyControl();
ViewState["AddRuleProperty"] = true;
}
private void AddRulePropertyControl()
{
RuleProperty Control = (RuleProperty)LoadControl("RuleProperty.ascx");
MyPanel.Controls.Add(Control);
}
Update.
If you want to remove the control from the page later on in the control's click handler, you need to remove corresponding ViewState key. This is not possible from the control directly, since property Page.ViewState is protected, and also this would have created an unwanted dependency.
What seems as the right way to do this is to subscribe to the very same event from the Page (you might need to make this event visible from the controller) and reset the key in there. Like this:
private void AddRulePropertyControl()
{
RuleProperty Control = (RuleProperty)LoadControl("RuleProperty.ascx");
Control.ButtonClick += RuleProperty_ButtonClick;
MyPanel.Controls.Add(Control);
}
private void RuleProperty_ButtonClick()
{
ViewState["AddRuleProperty"] = false;
}
Please note that event name here is not real, this is just a sketch of what can be done.
I am aware that many of the content pages will create textBox controls with lets say txtCustomerName. And if this is found I need to update the value from session. In this particular case I can not move these controls to master page.
How do you access page controls from master page. And in which event of page life cycle should we attempt to do this ?
You can find in any Event you would like to, like in this example I am showing you on Button Click Event
protected void Button1_Click(object sender, EventArgs e)
{
TextBox TextBox1 = ContentPlaceHolder1.FindControl("TextBox1") as TextBox;
if (TextBox1 != null)
{
Label1.Text = TextBox1.Text;
}
}
Good morning everybody.
I have a question connected with controls and event handling. Lets say I want to create a LinkButton.
protected void loadLinkButton()
{
ContentPlaceHolder content = (ContentPlaceHolder)this.Master.FindControl("MainContent");
LinkButton lnk = new LinkButton();
lnk.ID = "lnikBtn";
lnk.Text = "LinkButton";
lnk.Click += new System.EventHandler(lnk_Click);
content.Controls.Add(lnk);
}
Here is the event handler:
protected void lnk_Click(object sender, EventArgs e)
{
Label1.Text = "ok!";
}
If I run the loadLinkButton function inside Page_Load everything is ok. But when I try to run the loadLinkButton by clicking simple button, link button is created but event is not handled.
protected void Button1_Click(object sender, EventArgs e)
{
loadLinkButton();
}
I there any way to solve it? Or loadLinkButton must always regenerated on Page_Load, Page_init etc.
When working with dynamic controls, I always add the control in Page_Init, because viewstate loading will happen right after Init. If you add it to Page_Load, there is a chance that you will lose viewstate. Just make sure you provide a unique control ID.
It is important to know how ASP.Net determines which events to invoke. The source of each event is passed using a hidden field:
<input type="hidden" name="__EVENTTARGET" value="" />
Whenever the page loads, it pulls in the source of the event from that field and then determines which event to invoke. Now this all works great for controls added through markup because the entire control tree is regenerated on every request.
However, your control was only added once. When a Postback occurs, your control no longer exists as a Server control in the tree, and therefore the event never fires.
The simply way to avoid this is to make sure your Dynamic Controls are added every time the page loads, either through the Page_Init event, or the Page_Load event.
You are right. This is the expected behavior. Page_Load and Page_Init would be the events where you should be adding it.
That would be because when you click your dynamically generated linkbutton, you do a postback to the server. There you do an entirely new pageload, but your original buttonclick (that generates the link) never happened now, so the linkbutton is never made, and the event can not be thrown.
An alternative is to add the linkbutton you add dynamically, to your page statically, with Visible = false. And when you click the other button, make it visible.
I am not exactly sure what problem you are facing but you should put the dynamic controls code in Page_Init as suggested by #johnofcross:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Page_Init(object sender, EventArgs e)
{
CreateControls();
}
private void CreateControls()
{
var lb = new LinkButton();
lb.Text = "Click Me";
lb.Click += lb_Click;
ph.Controls.Add(lb);
ph.DataBind();
}
void lb_Click(object sender, EventArgs e)
{
lblMessage.Text = "Button is clicked!";
}
}
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) // If page loads for first time
{
Session["update"] = Server.UrlEncode(System.DateTime.Now.ToString()); // Assign the Session["update"] with unique value
//=============== Page load code =========================
//============== End of Page load code ===================
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Session["update"].ToString() == ViewState["update"].ToString()) // If page not Refreshed
{
//=============== On click event code =========================
Label1.Text = TextBox1.Text;
//lblDisplayAddedName.Text = txtName.Text;
//=============== End of On click event code ==================
// After the event/ method, again update the session
Session["update"] = Server.UrlEncode(System.DateTime.Now.ToString());
}
else // If Page Refreshed
{
// Do nothing
}
}
protected override void OnPreRender(EventArgs e)
{
ViewState["update"] = Session["update"];
}
}
This is not working for high resolution gradient background.
Consider wrapping your button and the label in an updatepanel control, which uses AJAX to refresh their contents.
The rest of the page will not be reloaded and the action will not affect the browser navigation.
See this page on how an updatepanel control works.
Since you are handling the button click event in server side there has to be a postback to handle it.
If you do not want a post back to happen change the event handling to "client click"
//Heinzi code worked for me just made a small change in OnPreRender event, assign the ViewsState value when its not post back
protected override void OnPreRender(EventArgs e)
{
if (!IsPostBack)
{
ViewState["update"] = Session["update"];
}
}