A) Question below is based on the assumption that controls are always binded to data source controls in the order they are declared? So in our example SqlDataSource1 will connect to data source prior to SqlDataSource2 and thus lstCities will be populated with values before GridView1, and reason for that being that lstcities was declared before GridView1?!
B) If so, then when exactly does ControlParameter retrieve a value from DropDownList? I assume it’s after SqlDataSource1_Selected() event handler and before SqlDataSource2_Selecting() event handler, but when precisely?
In .aspx page:
<asp:SqlDataSource ID="SqlDataSource1" ... >
</asp:SqlDataSource>
<asp:DropDownList ID="lstCities" DataSourceID="SqlDataSource1"
DataTextField="City" runat="server"></asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource2" ... >
<SelectParameters>
<asp:ControlParameter ControlID="lstCities" Name="City"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
<asp:GridView DataSourceID="SqlDataSource2" runat="server" …>
</asp:GridView>
thanx
EDIT:
If it is a postback, however, then those parameters will get loaded from a viewstate on the page's OnLoadComplete, again, in the order they are declared.
Q1 – Let’s assume ControlParameter is bound to property C1 of a control C. I would imagine that on postbacks ControlProperty would always be able to get C.C1’s value from ViewState, no matter of what type C is, and even if C has ViewState disabled?!
Q2 – But may I ask why, if a page is created for the first time, can’t a value for ControlParameter also be retrieved from viewstate? Afterall, the moment lstCities retrieves data from data source, lstCities.SelectedValue has its value set?
thanx mate
SECOND EDIT:
I apologize for not replying sooner, but I didn’t realize you’ve replied. And when I did, I've spent good 20 minutes trying to get my 3 braincells to work properly, but I'm not sure if I quite succeeded
A) So ControlParameter evaluates C.C1 and thus retrieves C.C1’s value after C has been bound?!
Q1 – ControlParameter only reads its own state and only to determine if it changed
A) So ControlParameter checks whether its ViewState changed ( in order to fire OnParameterChanged event) before binding takes place –> thus it checks its ViewState during Page.OnLoadComplete.
But how will ControlParameter know that its ViewState has changed ( it will know on first postback )? Afterall, from the first time the page is created ControlParameter’s ViewState will always be marked as dirty, so how will, from one postback to another, ControlParameter know whether its value has changed between postbacks?
B) I assume ControlParameter checks whether its Viewstate changed only so that it can fire OnParameterChanged event. But why is handling that event so important?
The first time a property evaluation happens is on Page.OnLoadComplete
By property evaluation you mean ControlParameter checking its own ViewState? Thus you don’t mean ControlParameter evaluating C.C1 ( which I assume happens after C has been bound )
I really appreciate your help
THIRD EDIT:
I’m really sorry for again taking your time.I will do my best to make this my last Edit.
Update() is called both in OnLoadComplete and when data binding takes place. Inside Update() the following sentence is also executed:
this.ViewState["ParameterValue"] = actualValue;
So if Update() is called when data binding takes place, then what that means is
that when on next postback UpDate() is called in OnLoadComplete, C.C1 and ControlParameter will already have same values and thus
if ((actualValue == null && storedValue != null)
|| (actualValue != null && actualValue != storedValue))
will always return false ( when Update() is called in OnLoadComplete ), and so OnParameterChanged event will never get fired?1 If so, the I fail to see the need to call Update() in OnLoadComplete!
much obliged
Best Answer
Your first assumption is correct.
To your second question, it depends on whether it is a post back or not and/or if you are binding explicitly. If it is not the post back and binding happens automatically then, roughly speaking, the value of the ControlParameter is retrieved when DataSourceView calls Select on DataBind, right before OnSelecting event. The sequence for the gridview (and any given control for that matter) is as follows:
So, for each control in a control hierarchy, the framework recursively calls DataBind, which then triggers retrieval of parameters, OnSelecting, data retrieval, and OnSelected.
If it is a postback, however, then those parameters will get loaded from a viewstate on the page's OnLoadComplete, again, in the order they are declared.
Is this what you were looking for?
Edit
That's not entirely how it happens... On post back (and on initial request for that matter), ControlParemeter's view state is evaluated only to see if it changed so that the OnParameterChanged event could get fired. The actual value of the ControlParameter is evaluated against the control it points to (via reflection). In your case it'd be "C.C1". Now, when it reads C.C1, its value is most likely read from a view state. But at no point does the ControlParameter read C's view state directly.
That's the thing, at that point (the first time page loads) the lstCities did not retrieve any data yet. The first time a property evaluation happens is on Page.OnLoadComplete, but before any DataBind (which happens shortly after, when Page.PreRenderRecursiveInternal gets fired).
In the crude form, trying to place it in a life cycle of a page:
Second Edit
The ControlParameter retrieves values whenever it is asked, which in this scenario happens (indirectly) in two places: OnLoadComplete and DataBind (triggered by PreRenderRecursiveInternal). On OnLoadComplete, the C is not bound. On PreRenderRecursiveInternal, after DataBind, the C is bound. Both times ControlParameter is asked to read C.C1. Maybe following will help...
Here are classes and methods of interest in a nutshell. Place them in perspective of the page cycle and hopefully it will be clear.
Refer to the UpdateValue method above to see how it uses ViewState.
I don't know that it is important. I suppose, like any other event, it allows you to track changes in parameter's properties and act accordingly to your needs. It gets fired in many places, but I don't see where anyone subscribes to it. So...
It means that the ControlParameter.UpdateValue gets called, which checks ViewState for stated reasons, then calls ControlParameter.Evalue, which then finds a control and retrieves data using reflection (Eval). See above.
Third Edit
I presume that by Update you mean UpdateValue.
Not necessary. You are forgetting that the view state is loaded on LoadAllState and between it and the OnLoadComplete there are six more steps (see page life-cycle above). Each of those may modify the source control's (C.C1) value.
Say you have C.C1 = "x" and did a post back. Now, the view state for all controls is loaded (LoadAllState). If C.C1 stored it's value in the view state, it will load "x". On Page_Load (LoadRecursive) you decide to set C.C1 = "y". Here C.C1 may decide to store "y" in its view state or not -- it's irrelevant. Then other events follow. Next comes OnLoadComplete. Since SqlDataSource subscribes to this event, it will evaluate all associated parameters (LoadCompleteEventHandler) and, since you did change C.C1 but ControlParameter's view state did not, the
will return true and OnParameterChanged will be fired. By the way, there is at least ten other places where this event gets triggered. It doesn't play big role (if any) in data binding and property retrieval process.