如果控件始终按照声明的顺序绑定到数据源控件,则
A) 下面的问题基于这样的假设:控件始终按照声明的顺序绑定到数据源控件? 因此,在我们的示例中,SqlDataSource1 将先于 SqlDataSource2 连接到数据源,因此 lstCities 将在 GridView1 之前填充值,原因是 lstcities em> 是在 GridView1 之前声明的?!
B) 如果是这样,那么 ControlParameter 何时从 DropDownList 中检索值? 我假设它在 SqlDataSource1_Selected() 事件处理程序之后和 SqlDataSource2_Selecting() 事件处理程序之前,但具体是什么时候呢?
在 .aspx 页面中:
<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
编辑:
但是,如果是回发,那么这些参数将从页面的 OnLoadComplete 上的视图状态加载,同样按照它们声明的顺序。
Q1 - 让我们假设 ControlParameter 绑定到控件 C 的属性 C1。我想在回发时 ControlProperty 总是能够从 ViewState 获取 C.C1 的值,无论 C 是什么类型,即使 C 是什么类型ViewState 被禁用了吗?!
Q2 - 但请问为什么如果第一次创建页面,则不能从视图状态中检索 ControlParameter 的值? 毕竟,当 lstCities 从数据源检索数据时,lstCities.SelectedValue 的值就设置好了?
谢谢伙伴
第二次编辑:
我很抱歉没有尽快回复,但我没有意识到你已经回复了。 当我这样做时,我花了 20 分钟试图让我的 3 个脑细胞正常工作,但我不确定我是否完全成功
A) 所以 ControlParameter 评估 C.C1 并因此检索 C.C1 的值C绑定后?!
Q1 - ControlParameter 仅读取其自身状态并仅确定其是否更改
A) 因此 ControlParameter 在绑定发生之前检查其 ViewState 是否更改(以便触发 OnParameterChanged 事件) --> 因此它会在 Page.OnLoadComplete 期间检查其 ViewState。 但是 ControlParameter 如何知道其 ViewState 已更改(它将在第一次回发时知道)? 毕竟,从第一次创建页面开始,ControlParameter 的 ViewState 将始终被标记为脏,因此,从一个回发到另一个回发,ControlParameter 如何知道其值在回发之间是否已更改?
B) 我假设 ControlParameter 检查其 Viewstate 是否更改,以便它可以触发 OnParameterChanged 事件。 但为什么处理该事件如此重要?
第一次进行属性评估是在 Page.OnLoadComplete
属性评估您的意思是 ControlParameter 检查它自己的 ViewState 吗? 因此,您的意思并不是说 ControlParameter 评估 C.C1 (我认为这发生在 C 被绑定之后)
我真的很感谢您的帮助
第三次编辑:
我真的很抱歉再次占用您的时间。我会尽力将其作为我的最后一次编辑。
Update() 在 OnLoadComplete 和数据绑定发生时都会被调用。 在 Update() 内部,还会执行以下语句:
this.ViewState["ParameterValue"] = actualValue;
因此,如果在数据绑定发生时调用 Update(),那么这意味着什么 当在 OnLoadComplete 中调用下一次回发 UpDate() 时,C.C1 和 ControlParameter 将已经具有相同的值,因此
if ((actualValue == null && storedValue != null)
|| (actualValue != null && actualValue != storedValue))
将始终返回 false(在 OnLoadComplete 中调用 Update() 时),因此 OnParameterChanged 事件永远不会被触发?1如果是这样,我看不出需要在 OnLoadComplete 中调用 Update() !
非常感谢
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的第一个假设是正确的。
对于你的第二个问题,这取决于它是否是回发和/或你是否明确绑定。 如果不是回发并且绑定自动发生,那么粗略地说,当 DataSourceView 在 OnSelecting 事件之前调用 DataBind 上的 Select 时,将检索 ControlParameter 的值。 gridview(以及与此相关的任何给定控件)的顺序如下:
因此,对于控件层次结构中的每个控件,框架递归调用 DataBind,然后触发参数检索、OnSelecting、数据检索和 OnSelected。
然而,如果它是回发,那么这些参数将从页面的 OnLoadComplete 上的视图状态加载,同样按照它们声明的顺序。
这是您要找的吗?
编辑
事情并不完全是这样发生的...在回发时(以及针对该问题的初始请求),仅评估 ControlParemeter 的视图状态以查看它是否发生更改,以便触发 OnParameterChanged 事件。 ControlParameter 的实际值根据它指向的控件进行评估(通过反射)。 在你的情况下,它是“C.C1”。 现在,当它读取 C.C1 时,它的值很可能是从视图状态读取的。 但 ControlParameter 绝不会直接读取 C 的视图状态。
就是这样,此时(页面第一次加载)lstCities 尚未检索任何数据。 属性评估第一次发生在 Page.OnLoadComplete 上,但在任何 DataBind 之前(当 Page.PreRenderRecursiveInternal 被触发时不久就会发生)。
以粗略的形式,尝试将其放入页面的生命周期中:
第二次编辑
ControlParameter 每当被请求时都会检索值,在这种情况下,这会(间接)发生在两个地方:OnLoadComplete 和 DataBind(由 PreRenderRecursiveInternal 触发)。 在 OnLoadComplete 上,C 未绑定。 在PreRenderRecursiveInternal上,在DataBind之后,C被绑定。 两次 ControlParameter 都被要求读取 C.C1。 也许以下内容会有所帮助...
简而言之,这里是感兴趣的类和方法。 将它们放在页面周期的角度,希望它会很清楚。
参考上面的UpdateValue方法看看它是如何使用ViewState的。
我不知道这很重要。 我想,就像任何其他事件一样,它允许您跟踪参数属性的变化并根据您的需要采取行动。 它在很多地方被解雇,但我看不到有人订阅它。 所以...
这意味着 ControlParameter.UpdateValue 被调用,它检查 ViewState 的原因,然后调用 ControlParameter.Evalue,然后找到一个控件并使用反射 (Eval) 检索数据。 往上看。
第三次编辑
我认为“更新”是指“更新值”。
没有必要。 您忘记了视图状态是在 LoadAllState 上加载的,并且在它和 OnLoadComplete 之间还有六个步骤(请参阅上面的页面生命周期)。 其中每一个都可能修改源控件的 (C.C1) 值。
假设您有 C.C1 =“x” 并进行了回发。 现在,所有控件的视图状态均已加载 (LoadAllState)。 如果 C.C1 将其值存储在视图状态中,它将加载“x”。 在 Page_Load (LoadRecursive) 上,您决定设置 C.C1 = "y"。 这里,C.C1 可能决定是否将“y”存储在其视图状态中——这无关紧要。 然后其他事件随之而来。 接下来是 OnLoadComplete。 由于 SqlDataSource 订阅了此事件,它将评估所有关联的参数 (LoadCompleteEventHandler),并且由于您确实更改了 C.C1 但 ControlParameter 的视图状态没有更改,因此
将返回 true,并且将触发 OnParameterChanged。 顺便说一句,至少还有其他十个地方可以触发此事件。 它在数据绑定和属性检索过程中没有发挥很大的作用(如果有的话)。
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.