Automatic data binding mysteries - asp.net

I have some questions about how and when data sources are bound in the page lifecycle, and I can't seem to find the answers anywhere.
I have a gridview which is bound to a data source at design time. One of the parameters for the DS is the selected value of a dropdown list. These dropdown lists are also databound to retreive their options, and the dropdowns have their auto-postback property set true. Now some things are confusing me about this.
Most of the time changing the value of the dropdown will reload the gridview with the new parameter, and it's not necessary to manually call databind() on the gridview in order to do so. However there are situations where the gridview is not rebound, and I'm not sure what these conditions are. When will a data-source be rebound automatically upon parameter change, and when do you need to call databind manually from code?
Does calling databind from codebehind prevent the automatic databind event from firing, or will they both fire, resulting in a wasteful extra query of the data source?
If the former, is there a way to stop the extra databind from occurring without having to move everything into code behind and lose the convenience of setting up data sources for the controls in the design view?
Are the answers to these questions documented on any official sources? (MSDN, etc)

I can't be sure without looking at you code, but you probably want to read about ViewState.
Once the control has been loaded, the data stays in the viewstate. You generally want to do the DataBinding on (!IsPostBack) event so that on postbacks you do not need to rebind the data from the DB.

Related

Which life-cycle event should I execute my code in order for it to be after a Gridview is completely loaded?

I have a quick question. I have a gridview that would generate a large result from a relatively long load time. I want to wait until the gridview is completely populated and loaded until I execute a certain code. Would I use this under Page_Load? I was looking at these life-cycles, and it looks like it could possibly fall into others as well, such as LoadComplete.
If the code is related to processing the GridView after it's complete, then the most obvious event would be the OnDataBound event.
Event Description
This method notifies a server control that any data binding logic
associated with the control has completed.
If you are explicitly populating the GridView with a DataBind, then do it after you call the DataBind.
If the GridView is populated "automatically" with a datasourceid= in the aspx page, then you can do whatever in the page load event.

Items in a Repeater are lost during a postback (callback)

Using ASP.NET 4.0 WebForms.
I have a repeater with checkboxes in it. The repeater and checkboxes have viewstate enabled. There's a button which causes a callback postback. These elements reside in a callbackpanel (similar to MS's UpdatePanel but doesn't use viewstate). The repeater is bound to a datatable during initial load and repeater shows the checkboxes. Fine so far.
During the postback (a callback), I noticed that the repeater's items' count is 0 in the page_load. Therefore I can't get any checkbox values. I can see the key/checked value entries of the checkboxes in Request.Form collection.
I think I am missing something obvious but where in the life cycle can I read the repeater's items?
Or should I get them from Request.Form?
1) Try wiring up to LoadComplete. All child controls are loaded recursively, so sometimes not everything you expect to be there will be present during the Load event.
2) Make sure your repeater is initialized during or prior to Init event. If you have some code that runs to populate it, then this must be executed in Init. During the page's lifecycle, ASP.NET tries to take the posted values and apply them to the controls. If the controls are not created soon enough during the lifecycle, then they won't exist during that step to accept the posted values. This is one of the more frustrating things with dynamic pages in ASP.NET, as you have to ensure the page is reconstructed during the postback in init. So even when you see the data in the post, ASP.NET will ignore it if the controls aren't found in its collection of controls. Also, there is some magic that happens with control IDs that it uses to map the posted values into the controls. I don't remember the details of that though because it has been several weeks since I had to delve into the harry details.
Also, make sure you aren't doing something like using if(!IsPostBack) to initialize your repeater or other controls/data. Even if it's a postback, you still need the controls to exist so they can accept the posted values.
I have not used a callbackpanel though, so I am unsure of how this will muddy the waters.
I solved my problem by overriding the DataBind method on the control which contains the repeater. That prevents DataBinds on parent controls from trickling down and binding data to the repeater when it isn't ready for that. My problem was that a parent control/page performed a DataBind which trickled down to the sub-controls, including the repepater, causing it to get cleared. So you don't have to do a DataBind directly on the repeater on every postback like #AaronLS suggests:
Also, make sure you aren't doing something like using if(!IsPostBack)
to initialize your repeater or other controls/data. Even if it's a
postback, you still need the controls to exist so they can accept the
posted values.
All my RepeaterItems were stay present through postbacks even though I only databind once.
In my case, performing a DataBind on the repeater for every postback caused the form values to be reset.

GridView Sorting without losing user modifications

I have a bit of a unique problem. I am using a GridView to display information from a database. The requirements for this GridView are that it is always editable so I have TextBoxes in the ItemTemplates and want to save the values when a button is clicked.
That all works great.
The problem is I am trying to get sorting (and eventually paging) working and hitting problems. If I bind the GridView from an ObjectDataSource this obviously doesn't work because it rebinds the datasource before it sorts and I lose any modified values. If I bind the GridView from a DataTable and try to store it in a Session variable it still doesn't work because any modified values aren't in the session variable.
I'm really just looking for suggestions on what I could possibly do to sort (and page later) without losing values the user has modified. I realize most people don't modify the Gridview all at once so its a weird problem.
You could implement client-side sorting of the GridView which would have the added benefit of making your UI feel faster. There is a blog post on sorting with jQuery you could try, though I have not personally used the method suggested.
Alternatively, you could send the values back to the server via AJAX while editing and save them (temporarily) in the session, the database, or where it makes the post sense in your scenario. You would obviously need to retrieve them when sorting.
One final option would be to save your values on the postback caused by the sort command. Mostly you would do something along the lines of handling the OnTextChanged event of the TextBoxes and (as above) saving the values to a temporary store. You would not want these TextBoxes to autopostback - they would simply wait for a postback such as the one caused by your sorting event. In this scenario you could also use the temporary store you populate during the save event to avoid duplicating the effort.

ASP.NET GridView problem

Well i have a gridview where i have defined the columns on my own and turned autogenerating off but now i have the problem that i cant access GridView.SelectedRow.DataItem.
As it turns out to be null now, when it had a value when auto generation was turned on..
Edit:
What i need is a way to save the ID of the row while not showing the ID to the user so if there is any way to do this?
I'm guessing DataItem is only properly filled when you are using DataBinding.
Are you using DataBinding?
Ok from this url:
The GridView (and actually, all our
data controls) does not save data
items across postbacks. This reduces
ViewState (if the objects are even
serializable) and enables garbage
collection to happen and clean up your
objects. So, when you click the
button to post back, the GridView has
not called DataBind and therefore your
data item isn't there. This is what
you've discovered.
Guessing you're reading the value from a postback, might just be the problem.
Try using SelectedValue, if you've setup the (primary) key for the items.
I've always used that and it worked.
msdn about SelectedValue
You can create a new hidden template column that will have a label with the ID . and in the cs file you use .FindControl on the rows.
You also have DataKeys property on the gridview, witch I think also does what you want

Nesting a GridView within Repeater

I have a scenario wherein, for example, I need to repeat a list of US states and display a table of cities and city populations after the name of each state. The design requirement dictates that every outer repetition must be the name of a state followed by a table of cities, and that requirement cannot be changed at this time. Are there disadvantages to nesting a GridView within a Repeater and then binding each repeated GridView during the Repeater's ItemDataBound event? What are some alternative solutions?
If it were me, I'd reverse the question and ask why I should use a GridView, If you need a bunch of built-in features like paging and sorting, then the GridView might be a good fit. If you just want tabular data, I'd reconsider. Why? Because with GridView you're getting a whole bunch of stuff you won't use, your ViewState will be potentially huge, and your page performance will be slower.
I'm not a bigot when it comes to GridView, but I only use them when there is a damn good reason.
In your above scenario, you'd be better off doing a master-detail style GridView, which will save you the overhead of all those GridView objects that get created.
There are various implementation of it (using a drop down for the master, using a modal popup for the detail, etc.), but the main point is that there are implementations available.
At the very least, hopefully you can turn off ViewState on the GridViews.
The best solution I was able to come up with was to nest the GridView in the Repeater. Then I bound each repeated GridView during the Repeater's ItemDataBound event. I turned off their ViewStates, of course, as they weren't required.

Resources