あなたの最初の仮定が正しいことを義務づけられ
。
あなたの2番目の質問には、それがポストバックかどうか、そして/または明示的にバインドしているかどうかによって異なります。それがポストバックではなく、自動的にバインディングが発生した場合、大まかに言って、DataSourceViewがOnSelectingイベントの直前にDataBindでSelectを呼び出すと、ControlParameterの値が取得されます。次のように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
、制御階層の各制御のために、フレームワークは再帰OnSelecting、次いで、パラメータの検索をトリガするのDataBindを呼び出し、データ検索、およびOnSelected。
ただし、ポストバックの場合、これらのパラメータは、ページのOnLoadCompleteのビューステートから、宣言された順序で再びロードされます。
この商品をお求めの客様はこんな商品もお求めです。
編集
Q1 - のは、ControlParameterが、私はポストバックにControlPropertyはいつものViewStateからC.C1の値を取得することができるだろうと想像制御C.のプロパティC1、どんなににバインドされていると仮定しましょうどのようなタイプCの、そしてCがViewStateを無効にしても?それが起こるか...ポストに戻って(そしてそのことについては、最初の要求で)完全ではありません
、ControlParemeterのビューステートがOnParameterChangedイベントがクビにすることができるようにそれが変更された場合にのみ見ることが評価されます。 ControlParameterの実際の値は、(反射を介して)指すコントロールに対して評価されます。あなたの場合、それは "C.C1"になります。さて、C.C1を読み込むと、その値はビュー状態から読み込まれる可能性が高くなります。しかし、ControlParameterはCのビューステートを直接読み取っていません。
Q2 - なぜ、ページが初めて作成された場合、ControlParameterの値もviewstateから取得できないのはなぜですか?その後、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.C1のを取得Cがバインドされた後の値?
それが求められるたびにControlParameterは、このシナリオでは2つの場所で(間接的に)発生した、値を取得: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)そのViewStateが変更されたかどうかそうControlParameterチェック...
は、ViewStateのを使用する方法を参照するには、上記UpdateValue方法を参照してください。
B)私はそれがOnParameterChangedイベントを発生することができるように、そのViewStateが唯一の変更されたかどうかControlParameterチェックを想定します。しかし、なぜそのイベントを扱うのが重要なのでしょうか?
私はそれが重要であるか分かりません。他のイベントと同様に、パラメータのプロパティの変化を追跡し、必要に応じて行動することができます。それは多くの場所で解雇されますが、私は誰がそれを購読しているのか分かりません。したがって...
プロパティ評価では、独自のViewStateをチェックするControlParameterを意味しますか?したがって、あなたはそれがその後、ControlParameter.Evalueを呼び出し、ControlParameter.UpdateValueが述べた理由のViewStateをチェックする、呼び出されることを意味します(私はCがバインドされた後に発生したと仮定)C.C1を評価ControlParameter
を意味するものではありません。これは、コントロールを見つけて、リフレクション(Eval)を使用してデータを取得します。上記を参照。
サード編集
私はアップデートによって、あなたがUpdateValueを意味すると推測。データバインディングが行われるとき
だから、update()が呼び出された場合、どのようなことが意味することは次のポストバックUpdateで()OnLoadComplete、C.C1とControlParameterに呼び出されたときに同じ値をすでにを持つことになります...
不要です。ビューステートがLoadAllStateにロードされていて、それとOnLoadCompleteの間にさらに6つのステップがあることを忘れています(上記のライフサイクルを参照)。それらのそれぞれは、ソースコントロールの(C.C1)値を変更することがあります。
C.C1 = "x"でポストバックしたとします。これで、すべてのコントロールのビューステートがロードされます(LoadAllState)。 C.C1がビューステートに値を格納すると、 "x"がロードされます。 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が発射されます。ちなみに、このイベントが発生する場所は少なくとも10箇所あります。データバインディングやプロパティの取得プロセスで大きな役割を果たすことはありません。
私は自分の答えを更新しました。一言で言えば、Q1 - ControlParameterは自身の状態だけを読み込み、それが変更されたかどうかを判断します。 Q2 - ControlParameterは常にCを評価します。C1であり、ビュー状態ではなく、その時点でC.C1は空であり(またはデフォルト)、ビュー状態に何もなく、まだデータバインディングが存在しないためである。 – Ruslan
いくつかのコードとともに詳細情報が提供されています。 – Ruslan