I need to load a web user control dynamically.
Looking at http://weblogs.asp.net/srkirkland/archive/2007/11/05/dynamically-render-a-web-user-control.aspx, it states that the page lifecycle events are not fired.
I thought I might be able to raise the events through reflection. I cannot figure how to fire the events, am I missing something?
Thanks
Podge
You can do something like this before calling RenderControl:
Page page = new Page();
page.Controls.Add(report);
In this case Init method will be called.
an answer given on that link of yours
The standard Load event should fire just fine. The standard ASP.Net control events are raised for usercontrols. If you are wanting to fire events inside your usercontrol from the parent page then you'll want to do something like this:
Inside your usercontrol create an event and wire it up. In this example I'll call it from Page_Load:
public event EventHandler TestEvent;
protected void Page_Load(object sender, EventArgs e)
{
if (this.TestEvent != null)
{
this.TestEvent(this, e);
}
}
Inside your parent page wire up the user controls TestEvent:
protected override void OnInit(EventArgs e)
{
MyUserControl uc = LoadControl("~/PathToUserControl.ascx");
uc.TestEvent += new EventHandler(MyUserControl_TestEvent);
}
protected void MyUserControl_TestEvent(object sender, EventArgs e)
{
//this code will execute when the usercontrol's Page_Load event is fired.
}
Hope that helps!!
Related
I have an imagebutton which i set up at design time via the designer and assigned a method to its Click event. I need to now change that buttons target event method dynamically.
I have tried this by setting the following code but it doesn't seem to alter the target event for the imagebutton to my desired method 'imgBtnFw_Click_Details'
imgBtn.Click +=new ImageClickEventHandler(imgBtnFw_Click_Details);
Im thinking maybe i need to detach the currently assigned click event but not sure.
Does anybody have a correct set of steps for switching the target firing event method?
Its working...
Event Binding..
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
imgBtn.Click -= ImageButton1_Click; // remove previous handler
imgBtn.Click +=imgBtnFw_Click_Details; // add new handler
}
}
Event handler ...
protected void imgBtnFw_Click_Details(object sender, ImageClickEventArgs e)
{
//your implementation
}
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 have a dropdownlist (on Page) which has OnSelectedIndexChange event thats Loads different Control (ascx) dynamically each time ( with LoadControl Command) - into the page.
Each Control Has a Button(runat=server) and TextBox(runat=server).
When i click on the button - i cant get into the Onclick function .
How can i get into the OnClick Function of the Ascx ?
I know that each SelectedIndexChange its makes postback - so i know i have to save something in the viewstate. but i dont know how to save it and later get the values eneterd on the TexstBox. ( of Each ascx)
You need to add an event handler to the user control, like this:
public event EventHandler ButtonClick;
And in the click event of the button:
protected void Button1_Click(object sender, EventArgs e)
{
if (this.ButtonClick != null)
this.ButtonClick(this, e);
}
Then, from the page, you can get the click event like this:
<UC:MyUserControl ID="UserControl1" runat="server" OnButtonClick="UserControl1_ButtonClick" ... />
protected void UserControl1_ButtonClick(object sender, EventArgs e)
{
//Handle the click event here
}
If you're loading the controls dynamically, then you'll need to make sure the controls are rehydrated after postback, and emulate the code above by assinging the event handler through code:
MyUserControl ctrl = (MyUserControl)this.LoadControl("...");
ctrl.ButtonClick += new EventHandler(UserControl1_ButtonClick);
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!";
}
}