Control caused the post back - asp.net

I have a form that contains a dropdownlist,
on index changed method,i will call my user control class .cs with parameters choosen by the user, when im putting my code inside the index changed like the code below, it doesnt work, which is a normal behavior:
protected void ResourceTypesDDL_SelectedIndexChanged(object sender, EventArgs e)
{
....
MyUsercontrol c = new MyUSercontrol(....);
this.panel.controls.add(c);
}
thats why i have to put the code inside my onload method, but the thing is how can i know if it is the ddl that caused the post back? is there a propertie? or should i use page.Request.Params.Get("__EVENTTARGET") technic ?
Thanks alot !

If your MyUserControl is really user control, that means .ascx file, you should use this:
Page.LoadControl("~/Controls/MyUserControl.ascx")
instead of creating the instance of the control by calling constructor directly.
protected void ResourceTypesDDL_SelectedIndexChanged(object sender, EventArgs e) {
....
var c = Page.LoadControl("~/Controls/MyUserControl.ascx");
this.panel.controls.add(c);
}
EDIT:
But of course, after every other post back, you will lose this control. So you should also make sure that you will create all dynamic controls during OnLoad event.

set the property autoPostBack=true on the dropdownlist in order for the page to postback
Or use the below function to get the post back control on the page_load
private string GetPostBackControl()
{
string retVal = string.Empty;
try
{
string ctrlname = Page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
Control ctrl = this.Page.FindControl(ctrlname);
if (ctrl != null)
{
retVal = ctrl.ID;
}
}
}
catch (Exception ex) { ManageException(ex, ShowGeneralErrorMessage); }
return retVal;
}

Try setting AutoPostBack="True" property of drop down list. After setting this property when you select an item in list it will automatically do the postback and your event ResourceTypesDDL_SelectedIndexChanged will be fired.

Related

How to reference a user control in its own code behind?

Let's say I have a user control with a couple of buttons. I'd like to know which one caused the postback, using this method:
public static Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}
And this is how I am calling it:
string btn = GetPostBackControl(this.Page).ID;
I'm getting the "Object reference not set to an instance of an object." I know now that the problem comes from the fact that I'm using this.Page, which represents the parent page.
How to reference the user control that I'm in? (not the parent page) So that it can work with the method to find the button that caused the postback?
Thanks for helping.
EDIT
Both buttons are located inside the user control. GetPostBackControl() is also in the code-behind of the user control.
I did a quick example on your given code and it worked out pretty fine. Perhaps you did miss checking for Page.IsPostBack? Obviously there will only be a postBackControl if there is a postBack...
#Buttons - they will be rendered as <input type="submit"> so they won't appear within ___EVENTTARGET. That's why Ryan Farlay wrote in his blog
However, you can still get to it, just in a different way. Since the
button (or input) is what causes the form to submit, it is added to
the items in the Form collection, along with all the other values from
the submitted form. [...] If you were to
look in the Form collection for anything that is a button then that
will be what caused the postback (assuming that it was a button that
caused the page to submit). If you first check the __EVENTTARGET, then
if that is blank look for a button in the Form collection then you
will find what caused the postback
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
Control postBackControl = GetPostBackControl(this.Page);
Debug.WriteLine("PostBackControl is: " + postBackControl.ID);
}
}
public static Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}

Why is my DropDownList empty on Postback?

I've looked at answers to some similar question but I still can't seem to figure this out. I think I'm misunderstanding something about how ASP.NET works.
In the standard ASP.Net 4.0 'Create a new Account' form, I've added a DropDownList containing Roles to be selected for the new account. in the aspx page, the control looks like this:
<asp:DropDownList ID="RoleList" Width="100px" runat="server"></asp:DropDownList>
I am then populating the List in the Page_Load Event:
protected void Page_Load(object sender, EventArgs e)
{
RegisterUser.ContinueDestinationPageUrl = Request.QueryString["ReturnUrl"];
if (Page.IsPostBack)
{
return;
}
//Set the Role List Selections
DropDownList roleList = (DropDownList)RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("RoleList");
//set the role list
String[] roles = Roles.GetAllRoles();
foreach (String role in roles)
{
roleList.Items.Add(new ListItem(role, role));
}
}
I can see/select a role from the generated html. The problem arises when the 'Submit' button for creating a User is clicked:
protected void RegisterUser_CreatedUser(object sender, EventArgs e)
{
FormsAuthentication.SetAuthCookie(RegisterUser.UserName, false /* createPersistentCookie */);
string continueUrl = RegisterUser.ContinueDestinationPageUrl;
if (String.IsNullOrEmpty(continueUrl))
{
continueUrl = "~/";
}
//set user role
DropDownList roleList = (DropDownList)RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("RoleList");
Roles.AddUserToRole(RegisterUser.UserName, roleList.SelectedValue);
Response.Redirect(continueUrl);
}
Here, The roleList object contains zero items, and has no selected values. Somehow, I am losing the populating items between selection of the item, and the submit. Any idea what I'm doing wrong?
Put your dropdownlist loading into the OnInit function instead - then it should be loaded properly when RegisterUser_CreatedUser is called:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//Set the Role List Selections
DropDownList roleList = (DropDownList)RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("RoleList");
//set the role list
String[] roles = Roles.GetAllRoles();
foreach (String role in roles)
{
roleList.Items.Add(new ListItem(role, role));
}
}
I had a similar issue that change of radio button selection would auto postback the page and the dropdown list items would disappear after the page is back.
Solution
Check IIS -> Your WebSite -> Pages & Controls -> Enable Viewstate & Enable Sessionstate should be set to true.
Hope this helps.
The code below bypasses the proper databinding on the page load.
if (Page.IsPostBack)
{
return;
}
You need to bind this control each time so that the values are present when click events are called. You may also get event errors for operating on selected items that are no longer present.
Did you try embracing your binding with the following condition?
if (!Page.IsPostBack)
{
//Binding goes here
}

Passing Value from textboxes in one webform to texboxes in another webform

am trying to get users to enter some details into a textbox in form1 and get the entry validated against the database. if the entry is correct, form2 loads with other texboxes including the one they made entries into. however i dont want them to make any changes to the textboxes they entered values into previously neither should they have to re-enter the values again.
how do i get the values in the textboxes to move from form1 to form2?
the code below shows what ive done with both forms but the second form dosent display the items in the textboxes when the form is loaded.
first form
protected void Button1_Click(object sender, EventArgs e)
{
string strConn;
strConn = "Provider=MIcrosoft.Jet.OLEDB.4.0;data Source=" +
Server.MapPath("App_Data/test.mdb");
OleDbConnection mDB = new OleDbConnection(strConn);
mDB.Open();
prodSnStr = pSnTextBox.Text;
purDate = Convert.ToDateTime(purDateTextBox.Text);
string dateStr = purDateTextBox.Text;
productClass aProduct = new productClass();
if (aProduct.Prods(mDB, prodSnStr, purDate))
{
Session["ProdSn"] = pSnTextBox.Text;
Session["PurDate"] = purDateTextBox.Text.ToString();
Response.Redirect("Warranty.aspx");
}
else
{
//error message
}
}
form two
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["ProdSn"] != "")
{
pSNoTextBox.Text = Request.QueryString["ProdSn"];
if (Request.QueryString["PurDate"] != "")
{
dateTextBox.Text = Request.QueryString["PurDate"];
}
else
{
//error message to display
}
}
else
{
//error message to display
}
}
eagaerly waiting for your responses..thanks..
In your code you are putting the values on one page into the session:
Session["ProdSn"] = pSnTextBox.Text;
Session["PurDate"] = purDateTextBox.Text.ToString();
However you are trying to read them out on the 2nd page from the Request collection:
if (Request.QueryString["ProdSn"] != "")
{
pSNoTextBox.Text = Request.QueryString["ProdSn"];
if (Request.QueryString["PurDate"] != "")
{
dateTextBox.Text = Request.QueryString["PurDate"];
}
This makes no sense. If you want to use the session, you must also get the values back out from the session object.
Personally I would look into Cross Page postbacks and Server.Transfer combined with Page.PreviousPage. Just make sure you don't set preserveForm parameter to false if using Server.Transfer.
You aren't passing your values as a query string. If you were your Response.Redirect would look like this:
Response.Redirect("Warranty.aspx?ProdSn=something&PurDate=something");
Instead since you are saving these values in a Session variable try this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["ProdSn"] != "")
{
pSNoTextBox.Text = Session["ProdSn"];
if (Session["PurDate"] != "")
{
dateTextBox.Text = Session["PurDate"];
}
else
{
//error message to display
}
}
else
{
//error message to display
}
}
In the button_click of the first form i entered this code
Session["ProdSn"] = pSnTextBox.Text;
Session["PurDate"] = purDateTextBox.Text.ToString();
Response.Redirect("Warranty.aspx?ProdSn=" + Server.UrlEncode(pSnTextBox.Text) +
"&PurDate=" + Server.UrlEncode(purDateTextBox.Text));
and then in the Page_load event of the second form i did this..
string value = Request["ProdSn"];
string value1 = Request["PurDate"];
pSnTextBox.Text = value;
purDateTextBox.Text = value1;
no hassle sustained....easy and perfectly working....
thank for ya'11 helping....
am very grateful
your asp.net page must post your data to second page.
just set your buttons PostBackUrl attribute.
<asp:Button ID="Button1" runat="server" Text="Button" PostBackUrl="target.aspx" />
I do not understand while you are making things complex.
When users clicks the button all data will be send to your target page.

Adding ImageButton Programmatically

I have a code snippet like below and I want to add imagebuttons into my asp:Panel during page load. But the events are firing already when I run the page. I want it to be fired when it is clicked.
Thanks in advance for all helps
protected void Page_Load(object sender, EventArgs e)
{...
foreach (Gift g in bonusGifts)
{
ImageButton ib = new ImageButton();
ib.ImageUrl = g.GiftBanner;
ib.ID = g.GiftID.ToString();
ib.Click += Purchase(g);
BonusGiftPanel.Controls.Add(ib);
}
}
private ImageClickEventHandler Purchase(Gift g)
{
_giftRep.Purchase(g, _userSession.CurrentUser);
lblGifts.Text = "You have purcased " + g.GiftName + " for " + g.BonusPoints;
return null;
}
Add controls in your Page_Init, not in your Page_Load. [1]
Furthermore, you are not doing this the way it should. Consider this code
//your collection of objects goes here. It might be something different than
//this, but basically a Dictionary<int, YourType> goes fine
public Dictionary<Int32, string> Ids
{
get { return (ViewState["ids"] ?? new Dictionary<Int32, string>()) as Dictionary<Int32, string>; }
set { ViewState["ids"] = new Dictionary<Int32, string>(); }
}
protected void Page_Init(object sender, EventArgs e)
{
//load the data using your DAO
Ids = new Dictionary<int, string>();
Ids.Add(1, "http://www.huddletogether.com/projects/lightbox2/images/image-2.jpg");
Ids.Add(2, "http://helios.gsfc.nasa.gov/image_euv_press.jpg");
foreach (var item in Ids)
{
ImageButton imb = new ImageButton()
{
ImageUrl = item.Value,
CommandArgument = item.Key.ToString(),
CommandName = "open"
};
imb.Click += new ImageClickEventHandler(imb_Click);
PH1.Controls.Add(imb);
}
}
void imb_Click(object sender, ImageClickEventArgs e)
{
Response.Write("You purchased " + Ids[int.Parse(((ImageButton)sender).CommandArgument)]);
}
[1] (CTRL+C/CTRL+V from some other question I answered last week):
Everything that has to be maintained between page cycles should be declared in Page_Init, not Page_Load.
All the initialization, like adding event handlers, and adding controls should be added during initialization, as the state is saved between page cycles. Handling with the content of controls and the viewstate, should be done in Load.
Check also http://msdn.microsoft.com/en-us/library/ms178472.aspx.
Init
Raised after all controls have been initialized and any skin
settings have been applied. Use this
event to read or initialize control
properties.
.
Load
The Page calls the OnLoad event method
on the Page, then recursively does the
same for each child control, which
does the same for each of its child
controls until the page and all
controls are loaded.
Use the OnLoad event method to set
properties in controls and establish
database connections.
You should add the controls in the Page Init event, as other have said.
Your image click event handler does not conform to the ImageButton Click event handler signature. That should look something like this:
private void ImageButton_Click(ByVal sender As Object, ByVal e As ImageClickEventArgs)
{
}
Note that you can't pass your "Gift" object directly to the ImageButton_Click. You will have to find another method of doing that.
You need to take a look at the Page Lifecycle - http://msdn.microsoft.com/en-us/library/ms178472.aspx

Prevent Page Refresh in C#

Duplicate of Asp.Net Button Event on refresh fires again??? GUID?
hello, ive a website and when a user click a button and the page postback, if the user refresh the Page or hit F5 the button method is called again.
any one know some method to prevent page refresh with out redirect the page to the same page again ?
something like if (page.isRefresh) or something... or if exist any javascript solution is better.
this seen to works.... but when i refresh it does not postback but show the before value in the textbox
http://www.dotnetspider.com/resources/4040-IsPageRefresh-ASP-NET.aspx
private Boolean IsPageRefresh = false;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["postids"] = System.Guid.NewGuid().ToString();
Session["postid"] = ViewState["postids"].ToString();
TextBox1.Text = "Hi";
}
else
{
if (ViewState["postids"].ToString() != Session["postid"].ToString())
{
IsPageRefresh = true;
}
Session["postid"] = System.Guid.NewGuid().ToString();
ViewState["postids"] = Session["postid"];
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (!IsPageRefresh) // check that page is not refreshed by browser.
{
TextBox2.Text = TextBox1.Text + "#";
}
}
Thanks for comments and sorry for my mistake,
I found this code in:
http://www.codeproject.com/KB/aspnet/Detecting_Refresh.aspx
And this time tested ;)
private bool _refreshState;
private bool _isRefresh;
protected override void LoadViewState(object savedState)
{
object[] AllStates = (object[])savedState;
base.LoadViewState(AllStates[0]);
_refreshState = bool.Parse(AllStates[1].ToString());
_isRefresh = _refreshState == bool.Parse(Session["__ISREFRESH"].ToString());
}
protected override object SaveViewState()
{
Session["__ISREFRESH"] = _refreshState;
object[] AllStates = new object[2];
AllStates[0] = base.SaveViewState();
AllStates[1] = !(_refreshState);
return AllStates;
}
protected void btn_Click(object sender, EventArgs e)
{
if (!_isRefresh)
Response.Write(DateTime.Now.Millisecond.ToString());
}
You can test for the Page.IsPostBack property to see if the page is responding to an initial request or if it's handling a PostBack such as your button click event. Here's a bit more information: w3schools on IsPostBack
Unfortunately that's not going to solve your problem since IsPostBack will be true when the user clicks the button as well as when they refresh the page after the button action has taken place.
If you're doing a task like performing CRUD on some data, you can Response.Redirect the user back to the same page when you're done processing and get around this problem. It has the side benefit of reloading your content (assuming you added a record to the DB it would now show in the page...) and prevents the refresh problem behavior. The only caveat is they still resubmit the form by going back in their history.
Postbacks were a bad implementation choice for the Asp.net and generally are what ruin the Webforms platform for me.
This doesn't solve the problem.
First of all, storing a token in the view state is not a good idea, since it can be disabled. Use control state instead. Although, a HttpModule is a better solution.
All in all, this will not work anyway. If you open another tab/window the session will be invalid for the previous tab/window. Therefore braking it. You must somehow store a unique value each time a page is first loaded. Use that to determine where the request came from and then check the "refresh ticket". As you may see, the object for one user might get pretty big depending on the amount of requests made, where and how long you store this information.
I haven't seen any solution to this I'm afraid, as it is pretty complex.
bool IsPageRefresh ;
if (Page.IsPostBack)
{
if (ViewState["postid"].ToString() != Session["postid"].ToString())
IsPageRefresh = true;
}
Session["postid"] = System.Guid.NewGuid().ToString();
ViewState["postid"] = Session["postid"];
I tried many ways and I ended up looking for the form data sent when the postback / refresh is triggered... I found that there is a Key for any VIEWSTATE created and you can just compare those Keys like...
I put that on my custom basepage to reuse it like an Property
public bool IsPageRefresh = false;
protected void Page_Init(object sender, EventArgs e)
{
if (IsPostBack)
{
var rForm = Request.Form;
var vw = rForm["__EVENTVALIDATION"].ToString();
var svw = Session["__EVENTVALIDATION"] ?? "";
if (vw.Equals(svw)) IsPageRefresh = true;
Session["__EVENTVALIDATION"] = vw;
}
}

Resources