I have a GridView on a page with a search button. The GridView is not visible to start with so that the user must click search before results are retrieved. The DataSourceID is set to the ID of an ObjectDataSource. When click is called, the following method is called from the click handler:
private void PopulateGrid()
{
gv.Visible = true;
gv.DataBind();
}
A problem occurs when the same method is called from the Page_Load handler. We store a user's search terms in their session and retrieve them the first time the page is accessed, something like this:
if(!PostBack && Session["search"] != null)
{
SetSearchFromSession();
PopulateGrid();
}
The problem in this case is that the ObjectDataSource's Selecting event is fired twice. Once when the GridView is made Visible, and again when DataBind() is called. I fixed this by substituting gv.Visible = true; for PopulateGrid(); in Page_Load.
But I'd like to understand what is going on. Why does setting GridView visible from page load result in DataBinding when a call in a button click event doesn't?
If you declaratively set the datasourceid then it is going to get called after PreRender and if you call DataBind it will be called again. (twice)
DataBinding
Raised after the control's PreRender event, which occurs after the
page's PreRender event. (This applies to controls whose DataSourceID
property is set declaratively. Otherwise the event happens when you
call the control's DataBind method.)
This event marks the beginning of the process that binds the control
to the data. Use this event to manually open database connections, if
required, and to set parameter values dynamically before a query is
run.
source
Related
I have a textbox, that programatically i set it 'Enabled = false'. When the page, after this change, get a postback, this textbox return the enabled value to true. why?
I have the textbox into a updatepanel.
If you're setting it in code-behind in the Page_Load event, you need to remember that Page_Load occurs even on postbacks. You have two options.
Place it with in a block that checks to see if the page is a postback.
if(!Page.IsPostBack)
{
TextBox1.Enabled = false;
}
or set it in Page_Init instead.
If you're not already familiar with it, be sure you understand the Page Lifecycle. This is must-know information for ASP.NET developers. Read about it at http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx
In the page_load, do the following:
If (IsPostBack) Then
Textbox1.Enabled = False
End If
I have the control dropdownlist which has been loaded inside the template column of RadGrid.
While loading I have set AutoPostBack='True' for dropdownlist and also created the event SelectedIndexChanged.
DropDownList ddlConditions = new DropDownList();
ddlConditions.ID = "ddl" + name;
ddlConditions.AutoPostBack = true;
ddlConditions.SelectedIndexChanged += new EventHandler(ddlConditions_SelectedIndexChanged);
My question is while i change the selected index of dropdownlist the event SelectedIndexChanged is not getting triggered.
Can anyone help me to solve this problem?
Thanks in advance.
Usually this caused by a page life cycle problem. When your index changed event of Dropdownlist fires the control doesn't exist to bind it on the postback.
Example:
-> MyEvent fires.
-> Drop-down created.
-> Event Handler specified.
-> Index Changed event triggered. Page reloads. Drop-down not found, cannot fire.
So you have to ensure that the drop-down is created before .NET attempts to handle the event.
Please refer this answer for more information regarding this type of issue and life cycle.
I can suggest you to check the place where you have created DropDownList. Dynamic controls should be added on OnInit or at least on OnLoad. After OnLoad finishes executing ASP.NET starts processing control's events and values.
My question is while i change the selected index of dropdownlist the
event SelectedIndexChanged is not getting triggered.
Answer: because you have created DropDownList after the events have been processed.
Is the page posting back? If so, you'll need to make sure that the control is recreated on the page on every postback.
If it's inside the usual if(!IsPostBack) block, then put it outside - Usually, it's prudent to create controls in page_init as well, but that can depend on your specific setup.
How do I conditionally trigger a full page postback from a link button inside of an update panel?
I have a custom control that contains its own updatepanel with a link button nested inside of it. When the link button is pressed I want its event handler to have the option of either letting the control update as normal or doing a full postback on the page.
Here is the control hierarchy:
Page
Custom Control
UpdatePanel
LinkButton
Event handler Pseudo code:
LinkButton Click Handler Begin
If is a partial post back AND a full postback is needed
Page.DoFullPostback
End If
End Handler
Note: I aways need the partial postback to happen. I was considering injecting a __DoPostback in the controls markup but this seems hacky to me.
Thanks for your help!
Sorry, I'm not familiar with the VB, so my example source will be written in C#:
protected void btnLink_Click(object sender, EventArgs e)
{
bool isAsync = ScriptManager.GetCurrent(Page).IsInAsyncPostBack;
bool postBackIsNeeded = true;
if (isAsync && postBackIsNeeded)
{
ScriptManager.GetCurrent(Page).RegisterPostBackControl(btnClick);
string postback = Page.ClientScript.GetPostBackEventReference(
btnClick,
string.Empty
);
ScriptManager.RegisterStartupScript(
btnClick,
btnClick.GetType(),
"postback",
postback,
true
);
}
}
The main idea is to change the type of postback of your LinkButton control. If neccessary it should be changed to full postback instead of partial during the async postback event. Right after this, another postback script should be generated and it should be executed as soon as the page will be returned to client.
And the last thing - use loop detection condition (if (isAsync && postBackIsNeeded) in my case) otherwise postback will be infinite.
The easiest approach is to create a hidden button somewhere on your page, outside of any UpdatePanels. When you need to do a full postback, use JavaScript to either click the button or issue __doPostback() to it. You can achieve a partial postpack programmatically in JavaScript by calling __doPostback() on an UpdatePanel itself, or to a button inside one.
I forgot to mention this asp.net 2.0.
The user control has a unique id and it is loaded in the PageLoad event.
The user control is loaded into a panel and the panel is inside of a webpart.
The dropdown has autopostback set to true.
EnableViewState = true on the dropdown.
The ListItems are created in the dropdowns pre-render event method.
This is why I don't understand why it is not firing, the dropdown is the only thing that causes postback on this user control.
The event methods for the dropdown should occur since the user control is loaded in the page load method on postback again right?
Make sure there is no OnLoad or PageLoad event that is rebinding the datasource of the dropdown list. Rebinding the data with a new set of data may cause the clickhandler to not ever get executed.
make sure you have if (!Page.IsPostBack) around dropdownlist.datasource = and dropdownlist.databind()
I am not sure if this is your problem, but it is the most common.
Try with EnableViewState set to
true for the DropDownList
If the ViewState is set to false, on post back the selected Index gets back to default which is normally the first Item. First item, if selected, does not cause SelectedIndexChange event to fire
On Page_Init I create a table of dynamically created controls based on a couple of database tables. One of the controls is an ImageButton for moving an list item up the list. What this event handler does is to update the SortOrder column in the database for the affected items.
Now the problem is that since the controls are created in the Page_Init event and the SortOrder is updated later on when the ImageButton command event is fired. What's the best procedure for updating the table with the correct SortOrder. If I recreate the table after the event has fired the ImageButton command event does not work any more.
Should I implement a method for updating the data in the table without recreating it?
Should I reload the page in code after the event has fired?
What's your preferred way for solving this problem?
Page events such as Init and Load will always fire before the event handler that raised the postback. This is the basis of the Page lifecycle (For a visual representation by Peter Bromberg, see here). Most developers new to ASP.NET have a major problem understanding and appropriately handling this "quandary".
The ideal way to do this is:
a. Your Page_Init should call a procedure (let's call it BindData() for illustration) that handles the creation of the table based on database data. This method would be similar to a binding method that binds to the database data and renders UI elements on the basis of that binding. IOW, you should remove the table creation code from the Page_Init method and put it in a separate method so that it can be called when needed.
Important note: This BindData() method also handles the attaching of the eventhandler for the dynamically created ImageButton control to the control. We'll call this ImageButton_Click. This is crucial for the control to the event to fire on subsequent postback.
b. When your ImageButton_Click method executes, it calls the BindData() method to recreate the table and it's bindings but with new sort order rules.
So, the order of execution on first load is:
Page_Init
BindData()
The order of execution on subsequent loads (on postback) is:
Page_Init
BindData() - Eventhandler for ImageButton attached.
ImageButton_Click
BindData()
You'll need something like this...
OnInit (IsPostBack = false)
Dynamically create ImageButton
Wireup ImageButton Event Handler
Load Table - Check for a sort-order in Session/Variable. If none; use the default
Click the button
OnInit (IsPostBack = true / 1st Postback)
Dynamically re-create ImageButton
Wireup ImageButton Event Handler
Load Table - with default sort order
ImageButton_OnClick (Still the same 1st postback)
Reload Table - with specific sort order
Save this sort-order variable in Viewstate/Session variable
Cause some other Postback
OnInit (IsPostBack = true / 2nd & Subsequent Postbacks)
Dynamically create ImageButton
Wireup ImageButton Event Handler
Load Table - Check for a sort-order in Session/Variable. If FOUND, use that.
Firstly, you seem to be binding your data manually to UI controls. In Asp.Net there and many ways to avoid this using built-in data binding techniques. Many controls like the GridView allow automatic creation of Html tables from a given data source. There are many other options including Repeaters.
However you do choose to bind your data, the technique is to rebind at some point every time through the page lifecycle.
You need to...
Bind you data on first page load with the default sort order
Rebind the data in the image button’s event handler after the sort order has been changed.
The code would look something like this...
private void Page_Load (...)
{
if (!IsPostBack)
//On First Load
BindData(defaultSoortOrder);
else
BindData(currentSortOrder);
}
private void ImageButton_Click (...)
{
currentSortOrder = newSortOrder;
BindData(currentSortOrder);
}
If the Image button is clicked, you will end up calling BindData twice. But this is necessary since a page postback could be initiated from any control, you need to always ensure you bind the data when the page loads.