如果控件始终是绑定到数据源控件的声明顺序排列,然后
-
05-09-2019 - |
题
结果
一个)问题下面是基于这样的假设控件始终绑定到数据源控件中声明它们的订单?因此,在我们的例子中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>
结果
感谢名单
编辑:
如果它是一个回传,但是,那么这些参数将得到从页面的一个的onLoadComplete加载视图状态,再次在声明顺序排列。 结果
Q1 - 假设ControlParameter绑定到控制C.我会想象在回发ControlProperty财产C1总是能够从ViewState中,没有什么类型C是,即使之事得到C.C1的值C有禁用ViewState的结果? 结果
Q2 - 不过,我可能问为什么,如果是第一次创建了一个页面,不能为ControlParameter值也可以从视图状态检索?毕竟,当下lstCities检索来自数据源的数据,lstCities.SelectedValue已经将其值设置?
搜索结果
感谢名单伴侣
结果
SECOND编辑:
我不及早回信,但是我不知道你已经回答。当我做到了,我花了整整20分钟试图让我的3个braincells才能正常工作,但我不知道如果我很成功。
结果
A)所以ControlParameter评估C.C1和C已经绑定之后从而检索C.C1的值?!
结果
结合前Q1 - ControlParameter只读取其自己的状态和只以确定它是否改变了
A)所以ControlParameter检查其是否视图状态改变(为了触发事件OnParameterChanged)发生 - >因而它检查Page.OnLoadComplete期间其视图状态。 但是,如何将ControlParameter知道它的ViewState已经改变(它会知道第一回发)?毕竟,从第一次创建ControlParameter的ViewState的页面总是被标记为脏的,所以怎么会从一个回发到另一个,ControlParameter知道它的价值是否已回发之间改变?
B)我假定ControlParameter检查其是否视图状态只改变,使得它可以触发事件OnParameterChanged。但是,为什么是处理该事件如此重要?
结果
在第一次的特性评价的情况是在Page.OnLoadComplete
通过财产评估你的意思是ControlParameter检查了自己的ViewState?因此,你并不意味着ControlParameter评估C.C1(我假定C已被结合后发生)
结果
我真的很感谢你的帮助。
结果
THIRD编辑: 结果
我再次把你再寄一次会尽我最大的努力使我最后的编辑真的很抱歉。
结果
更新()都在的onLoadComplete和当数据绑定发生被调用。内部更新()下面的句子也执行:
this.ViewState["ParameterValue"] = actualValue;
因此,如果更新()当数据绑定发生被调用,那么这意味着什么是 该上下一回发更新)时(被称为在的onLoadComplete,C.C1和ControlParameter已经将有相同的值,从而
if ((actualValue == null && storedValue != null)
|| (actualValue != null && actualValue != storedValue))
将始终返回false(时更新()中的onLoadComplete被调用),所以OnParameterChanged事件永远不会被解雇?1如果是这样,我看不到有需要的onLoadComplete来调用Update()!
结果
非常感谢
解决方案
您第一个假设是正确的。
要你的第二个问题,这取决于它是否是一个回与否和/或如果你明确地结合。如果不是后回来,结合自动发生的话,粗略地讲,在ControlParameter的值时的DataSourceView上的DataBind调用选择,OnSelecting事件前右检索。为GridView序列(和与此有关的任何给定的控制)如下:
Page.ProcessRequest
Page.PreRenderRecursiveInternal
...
GridView.EnsureChildControls
GridView.CreateChildControls
GridView.DataBind
GridView.PerformSelect
DataSourceView.Select //comes from either SQLDataSource or LinqDataSource
DataSourceView.ExecuteSelect
//for Linq:
LinqDataSourceView.GetParameterValues(WhereParameters)
//for SQL:
SqlDataSourceView.InitializeParameters(SelectParameters)
Parameters.GetValues
Parameters.UpdateValues //this is where values get retrieved using reflection
DataSourceView.OnSelecting //follows almost immediately
...get data...
DataSourceView.OnSelected
因此,对于在控制层次每个控制,该框架递归调用的DataBind,然后触发的参数检索,OnSelecting,数据检索,并OnSelected。
如果它是一个回传,但是,那么这些参数会得到从视图状态加载页面的的onLoadComplete,再次,在他们声明的顺序。
这是你要找的是什么?
修改强>
Q1 - 假设ControlParameter绑定到控制C.我会想象在回发ControlProperty财产C1总是能够从ViewState中,没有什么类型C是,即使之事得到C.C1的值C已禁用ViewState的?!
这不完全是怎么回事了......在回传(以及与此有关的初始请求),ControlParemeter的视图状态时,才会评估,看它是否改变,从而OnParameterChanged事件可能会被解雇。的ControlParameter的实际值与它(通过反射)指向控制进行评价。在你的情况下,它会是“C.C1”。现在,当它读取C.C1,它的价值是最有可能从一个视图状态读取。但在任何时候并在ControlParameter直接读取C'S视图状态。
Q2 - 不过,我可能问为什么,如果是第一次创建了一个页面,不能为ControlParameter值也可以从视图状态检索?毕竟,当下lstCities检索来自数据源的数据,lstCities.SelectedValue已经将其值设置?
这事情是这样的,在这一点上(第一次页面加载)的lstCities未检索到任何数据。第一次特性评价发生的是上Page.OnLoadComplete,但在此之前的任何的DataBind(其不久之后,当Page.PreRenderRecursiveInternal得到射击发生的)。
在粗品形式,试图将其放置在页面的生命周期:
...request...
PerformPreInit
InitRecursive //SqlDataSource subscribes to Page.LoadComplete
OnInitComplete
if PostBack
LoadAllState //the view state gets loaded
ProcessPostData
OnPreLoad
LoadRecursive
if PostBack
ProcessPostData
RaiseChangedEvents
RaisePostBackEvents //you handle your events
//notice that following sections assume that you did not do any data
//binding inside your events
OnLoadComplete //This is where parameters (SelectParemeters/WhereParemeters)
//get updated. At this point none of them are data bound yet.
//And if it the first time, there are no values
//as the ViewState is empty for them.
PreRenderRecursiveInternal //calls the DataBind (if you haven't already),
//then DataSourceView.Select; parameters evaluate their controls.
//The control C would be bound at this point.
PerformPreRenderComplete
SaveAllState
OnSaveStateComplete
RenderControl
<强>第二修改
所以ControlParameter评估C.C1和C已经被绑定后,从而获取C.C1的价值?!
在ControlParameter检索每当它被要求值,其在这种情况下在两个地方发生(间接地):的onLoadComplete和的DataBind(由PreRenderRecursiveInternal触发)。上的onLoadComplete中,C不绑定。在PreRenderRecursiveInternal,的DataBind之后,C为界。这两次ControlParameter被要求阅读C.C1。也许下面将有助于...
下面是类和的简而言之兴趣的方法。将它们放置在页面周期的透视图和希望这将是清楚的。
public class ControlParameter : Parameter
{
public string ControlID { get; set; } //stored in ViewState
public string PropertyName { get; set; } //stored in ViewState
protected override object Evaluate(HttpContext context, Control owner)
{
Control sourceControl = DataBoundControlHelper.FindControl(owner, this.ControlID);
//evaluate C.C1 using reflection
return DataBinder.Eval(sourceControl, this.PropertyName);
}
internal void UpdateValue(HttpContext context, Control owner)
{
//PostBack or not, read stored value (on initial load it is empty)
object storedValue = this.ViewState["ParameterValue"];
//Get the actual value for this parameter from C.C1
object actualValue = this.Evaluate(context, owner);
//Store received value
this.ViewState["ParameterValue"] = actualValue;
//Fire a change event if necessary
if ((actualValue == null && storedValue != null)
|| (actualValue != null && actualValue != storedValue))
this.OnParameterChanged();
}
}
public class SqlDataSource : DataSourceControl
{
//fired by OnLoadComplete
private void LoadCompleteEventHandler(object sender, EventArgs e)
{
//UpdateValues simply calls the UpdateValue for each parameter
this.SelectParameters.UpdateValues(this.Context, this);
this.FilterParameters.UpdateValues(this.Context, this);
}
}
public class SqlDataSourceView : DataSourceView, IStateManager
{
private SqlDataSource _owner;
//this method gets called by DataBind (including on PreRenderRecursiveInternal)
protected internal override IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
{
DbConnection connection = this._owner.CreateConnection(this._owner.ConnectionString);
DbCommand command = this._owner.CreateCommand(this.SelectCommand, connection);
//This is where ControlParameter will read C.C1 values again.
//Except this time, C.C1 will be already populated by its own DataBind
this.InitializeParameters(command, this.SelectParameters, null);
command.CommandType = GetCommandType(this.SelectCommandType);
SqlDataSourceSelectingEventArgs e = new SqlDataSourceSelectingEventArgs(command, arguments);
this.OnSelecting(e);
if (e.Cancel)
return null;
//...get data from DB
this.OnSelected(new SqlDataSourceStatusEventArgs(command, affectedRows, null));
//return data (IEnumerable or DataView)
}
private void InitializeParameters(DbCommand command, ParameterCollection parameters, IDictionary exclusionList)
{
//build exlusions list
//...
//Retrieve parameter values (i.e. from C.C1 for the ControlParameter)
IOrderedDictionary values = parameters.GetValues(this._context, this._owner);
//build command's Parameters collection using commandParameters and retrieved values
//...
}
}
A)所以ControlParameter检查其是否视图状态改变...
请参考上述UpdateValue方法,看看它如何使用视图状态。
B)我假定ControlParameter检查其是否视图状态只改变,使得它可以触发事件OnParameterChanged。但是,为什么是处理该事件如此重要?
我不知道这是很重要的。我想,像任何其他情况下,它可以让你追踪参数的属性变化,并采取相应的行动,以您的需求。它得到许多地方解雇,但我没有看到任何人都订阅了它。所以......
通过财产评估你的意思是ControlParameter检查了自己的ViewState?因此,你不是说ControlParameter评估C.C1(我假设发生C有B之后EEN结合的)
这意味着,ControlParameter.UpdateValue被调用,这对于所述的原因检查ViewState中,然后调用ControlParameter.Evalue,然后找到一个控制和使用检索数据反射(EVAL)。见上文
<强>第三修改
我相信,通过更新你的意思是UpdateValue。
所以,如果更新()当数据发生结合被调用,那么这是什么意思是,当在下次回发更新()被调用的onLoadComplete,C.C1和ControlParameter已经将有相同的价值观......
不必要的。你忘记了,视图状态被装载在LoadAllState,它和的onLoadComplete之间有六个步骤(见网页上面的生命周期)。每个那些可以修改源控制的(C.C1)值。
假设你有C.C1 =“X”,做了回发。现在,对于所有控制的视图状态被加载(LoadAllState)。如果C.C1存储它在视图状态值,它会载入“×”。在的Page_Load(LoadRecursive)你决定设置C.C1 = “Y”。这里C.C1可以决定存储的“y”的视图状态或不 - 这是无关紧要的。那么其他事件均遵循。接下来是的onLoadComplete。由于SqlDataSource的赞同这种情况下,它会评估所有相关的参数(LoadCompleteEventHandler),而且由于你没有改变C.C1但ControlParameter的视图状态没了,
if ((actualValue == null && storedValue != null)
|| (actualValue != null && actualValue != storedValue))
this.OnParameterChanged();
将返回true和OnParameterChanged将被解雇。顺便说一句,还有其他至少十个地方,该事件被触发。它没有起到数据很大的作用(如果有的话)结合和属性检索的过程。