2009-04-07 12 views
2


コントロールは、常に彼らは、その後

A宣言されているために、データソースコントロールにバインドされている場合)質問はコントロールは常にそれらが宣言されているために、データソースコントロールにバインドされていることを前提としていますか?だから、私たちの例ではSqlDataSource1前SqlDataSource2にデータソースに接続しますので、lstCitiesGridView1前に値が移入され、その理由はlstcitiesが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> 


ありがとう

EDIT:

それがポストバックである場合は、しかし、その後、それらのパラメータは、AからロードされますページのOnLoadCompleteのviewstateを、宣言されている順に再度実行します。

Q1 - どのタイプCの関係なくはある、のは、ControlParameterが、私はポストバックにControlPropertyはいつものViewStateからC.C1の値を取得することができるだろうと想像制御C.のプロパティC1にバインドされていると仮定しましょう、そしてCがViewStateを無効にしたとしても?

Q2 - しかし、ページが初めて作成された場合、私は、なぜ求めることができる、ControlParameterの値はまた、ビューステートから取得することはできませんか?その後、lstCitiesはデータソースからデータを取得し、lstCities.SelectedValueの値は設定されていますか?



ありがとうメイト


SECOND EDIT:

私はすぐに返信ないために謝罪、私はあなたが答えてきた実現しませんでした。私が行ったときに、私はそうControlParameterがC.C1を評価)正常に動作するために私の3 braincellsを取得しようとしているが、私はかなり


Aを成功した場合、私はわからないんだけど良い20分を費やしてきたし、 Cがバインドされた後C.C1の値を取得しますか?


はQ1 - ControlParameterは、自身の状態を読み取り、それが

Aを変更した場合にのみ前)OnParameterChangedイベントを発生させるために(そのViewStateが変化したか否か)がControlParameterチェックを決定しますバインドが行われます - >したがって、PageOnLoadComplete中にViewStateをチェックします。 しかし、ControlParameterはViewStateが変更されたことをどのように知っていますか(最初のポストバック時にはわかります)後で、ページが初めて作成されてから、ControlParameterのViewStateは常にダーティとマークされるので、ポストバックからControlParameterへの値はポストバックの間に値が変化したかどうかを知ることができますか?

B)OnParameterChangedイベントを発生させることができるように、ViewStateが変更されたかどうかをControlParameterがチェックすると仮定します。しかし、なぜそのイベントを扱うのが重要なのでしょうか?


特性評価は、最初に発生したときは、あなたがControlParameterは、独自のViewStateをチェックする意味特性評価によってPage.OnLoadComplete

にありますか?したがって、あなたはあなたの助け


は、私は本当に感謝しControlParameterが(私はCがバインドされた後に発生したと仮定)C.C1を評価するという意味ではありません


THIRD EDIT:

私は本当にもう一度あなたの時間を取って申し訳ありません。私はこれを最後の編集にするために全力を尽くします。


アップデートは、()OnLoadCompleteの両方と呼ばれたときにデータ・バインディングが行われています。アップデートの中に()は、以下の文も実行されます。

this.ViewState["ParameterValue"] = actualValue; 

だからアップデート()が呼び出された場合、データバインディングが行われたときに、その次のポストバックUpdateで()OnLoadCompleteで呼び出されたときということ で何を意味するのか、 C.C1とControlParameterはすでに同じ値を持つことになりますので、(update()がOnLoadCompleteで呼び出されたとき)

   if ((actualValue == null && storedValue != null) 
      || (actualValue != null && actualValue != storedValue)) 

は常にfalseを返し、そうOnParameterChangedイベントが発生しない飽きないでしょうか?1もしそうなら、私は失敗OnLoadCompleteでUpdate()を呼び出す必要があることを確認してください!ずっと

+0

私は自分の答えを更新しました。一言で言えば、Q1 - ControlParameterは自身の状態だけを読み込み、それが変更されたかどうかを判断します。 Q2 - ControlParameterは常にCを評価します。C1であり、ビュー状態ではなく、その時点でC.C1は空であり(またはデフォルト)、ビュー状態に何もなく、まだデータバインディングが存在しないためである。 – Ruslan

+0

いくつかのコードとともに詳細情報が提供されています。 – Ruslan

答えて

2

あなたの最初の仮定が正しいことを義務づけられ


あなたの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箇所あります。データバインディングやプロパティの取得プロセスで大きな役割を果たすことはありません。

+0

あなたのお手伝いをしたい場合に備えて私の質問を更新しました – SourceC

+0

もう一度迷惑をかけて申し訳ありませんが、時間を見つけた場合は別の編集を行いました。私のスレッドに行った編集に関するコメントを使って、(あなたに通知する方法で)人々に通知するか、またはそれは害虫とみなされますか?これは – SourceC

+0

と間接的に私に尋ねます。 – SourceC

関連する問題