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
}
Related
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 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
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!!
I'm getting into event handling now, and it seems quite confusing to me. See, I come from a web-dev background, so this event stuff is quite new to me.
I'm developing in C# / VS08 and created my Application in the WinForm-Designer.
Now, I created this program overview;
ProgramContext
MainForm : Form
LoginForm : Form
So, what I want to do is when the user clicks "Logout" (What is a menu item in the MainMenu of MainForm), that the application logs out the user.
But how can I access the "Click" event of the logout item from the ProgramContext's view, as there is all the logic of logging in etc.
I tried the following
MenuItem[] findLogout = MainMenuStrip.Items.Find("logoutMenuItem", true); // Throws NullPointerException
findLogout[0].Click += new EventHandler(LogoutClick);
private void LogoutClick(object sender, EventArgs e)
{
// Logout user
}
But keep getting a NullPointerException at the first line.
Easiest thing to do is to expose an event on MainForm:
public EventHandler LogOut;
Then hook into this from your ProgramContext:
MainForm form = new MainForm();
form.LogOut += new EventHandler(MainForm_LogOut);
void MainForm_LogOut(object sender, EventArgs e)
{
// Logout
}
Then fire the LogOut button is pressed on the MainMenu using the following code in the Menu Item's click event:
private void LogoutClick(object sender, EventArgs e)
{
if (LogOut != null)
{
LogOut(sender, e);
}
}
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"];
}
}