I am building an ASP.NET custom server control.
I have implemented both the IPostBackDataHandler and IPostBackEventHandler.
OnPreRender I have registered the postback logic:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (Page != null)
{
Page.RegisterRequiresRaiseEvent(this);
Page.RegisterRequiresPostBack(this);
}
}
The control uses a ImageButton (but I have also tried with a simple Button); when it is clicked I can see the page "refreshes", and some data are posted (I checked that).
However, I don't know why the RaisePostBackEvent(string eventArguments) is not firing.
Does anyone know what's going on? Could someone point me to the right direction to solve this?
Thanks in advance,
Cheers,
Gianluca.
Registering your control during PreRender phase is too late. You can do it during the Load phase instead:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (Page != null && Page.IsPostBack)
{
Page.RegisterRequiresRaiseEvent(this);
Page.RegisterRequiresPostBack(this);
}
}
Related
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")
{
...
}
...
}
I have the next code.
protected void Page_PreRender(object sender, EventArgs e)
{
bool isDelayWarning = proxy.MerchantPaySystemSetting_IsHoldPaymentsAllow(clientID, PaySystem.Type));
ViewState.Add("IsDelayWarning", isDelayWarning);
}
protected void btnSend_Click(object sender, EventArgs e)
{
if ((bool)ViewState["IsDelayWarning"] && !cbxDelayConfirm.Checked)
{
this.CustomErrorMessage = Yandex_Term_Error;
return;
}
}
In btnSend_Click method ViewState["IsDelayWarning"] = null.
How can I resolve this trouble?
Thanks! :)
I'm not sure about the logic you're going for, but a button push happens during post-back, before the page is rendered. Put breakpoints in your two methods to see their relative order.
Pay attention to the yellow marked items, control event processing is one of them and it happens strictly before PreRender.
You can always check for null reference by doing something like this
if (something != null)
code ------
or another way if you will sometimes have null is to use. For example if user address is null
if (thisuser.Address == null)
{
thisuser.Address = new Address();
}
thisuser.Address = user.Address.City;
I have created a User Control(Popupcontrol) and in that control i have created a property(PageType) and when i am using the Popupcontrol on the page then i set the property(pagetype) according to the page.
but now there is some problem i have to two button on the page and on the second button click i want to change the pagetype property .So is there any solution for the same.
Based on your comment, it seems you bind the data (PageType property in your question) in the Page_Load event, instead of this it should be done in overrided DataBind method which should be called if the page is not in post back request (otherwise your data will be overwritting in the next Page_Load event as you mentioned in your comments):
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
DataBind();
}
}
public override void DataBind()
{
PageType = someValue;
}
after this your click handler may looks like:
protected void button2_Clicked(object sender, EventArgs e)
{
PageType = someOtherValue;
}
Are you setting the variable in a page load event? You may need to add:
if (!Page.IsPostback) {
// Code here.
}
I have a page Product.aspx,there I have a user control ProductDisplay.ascx which has been created by drag and drop.
Now when a button is clicked in ProductDisplay.ascx,I want a logging function to be called which is in Product.aspx.
To achieve this I have used delegates
on ProductDisplay.ascx
public delegate void LogUserActivity(ProductService objService);
public event LogUserActivity ActivityLog;
on Product.aspx
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ProductDisp.ActivityLog += new User_UserControl_ProductDisplayBox.LogUserActivity(LogProduct);
}
}
Now button click event of ProductDisplay.ascx
protected void imgBtnBuyNow_Click(object sender, ImageClickEventArgs e)
{
if (ActivityLog != null)
{
ActivityLog(Product);
}
Response.Redirect("~/User/ShoppingCart.aspx");
}
My problem is that whenever i click this button ActivityLog is null.Why is it null?
My idea is that once i click this button,page posts back and its previous state is lost.
Please help me out with a reason and solution.
Secondly,I want to do away with null checking
**if (ActivityLog != null)**
{
ActivityLog(Product);
}
I saw some code which instantiates a delegate with a default value the moment it is declared,but i was not able to find it.Please help.
I have found solution to first problem
if (!IsPostBack)
{
ProductDisp.ActivityLog += new User_UserControl_ProductDisplayBox.LogUserActivity(LogProduct);
}
This was causing the issue.Move this line
ProductDisp.ActivityLog += new User_UserControl_ProductDisplayBox.LogUserActivity(LogProduct);
out of if (!IsPostBack)
I need to insert a bit of Javascript into the process when a Web Form is submitted, but after the client side validation takes place.
RegisterOnSubmitStatement seems to place the javascript before the validation.
Anyone know how to get it to render after?
Solution found:
In a web control, I put something like this:
protected override OnInit(EventArgs e) {
Page.SaveStateComplete += new EventHandler(RegisterSaveStuff);
base.OnInit(e);
}
void RegisterSaveStuff(object sender, EventArgs e) {
Page.ClientScript.RegisterOnSubmitStatement(typeof(Page), "name", "JS code here");
}
that´s right, the RegisterOnSubmitStatement DO NOT WORK in the init function.
It should be called after in the page lige cycle.
I thing the right place therefor is:
"PreRenderComplete"
protected override OnInit(EventArgs e)
{
Page.PreRenderComplete+= new EventHandler(Page_PreRenderComplete);
base.OnInit(e);
}
void Page_PreRenderComplete(object sender, EventArgs e)
{
Page.ClientScript.RegisterOnSubmitStatement(typeof(Page), "name", "JS code here");
}
After some research online and playing around with it, I figured out that you can do it by hooking into the Page's SaveStateComplete event. I guess the validation submit statement is registered during the PreRender event, so if you register it after that (in the SaveStateComplete event) you can get it afterward.
You do have to re-register it, but that's not a big deal because I'm not relying on ViewState for my JS.