Se i controlli sono sempre binded ai controlli origine dati nell'ordine in cui sono dichiarati poi

StackOverflow https://stackoverflow.com/questions/727274

Domanda

A) Domanda di seguito si basa sul presupposto che i controlli sono sempre binded ai controlli origine dati nell'ordine in cui sono dichiarati? Quindi, nel nostro esempio SqlDataSource1 si collegherà alla fonte di dati prima di SqlDataSource2 e quindi lstCities verrà popolata con i valori prima di GridView1 , e la ragione per questo essere che lstcities è stato dichiarato prima di GridView1 ?!


B) In caso affermativo, poi quando fa esattamente ControlParameter recuperare un valore da DropDownList ? Penso che sia dopo il SqlDataSource1_Selected () gestore di eventi e prima di SqlDataSource2_Selecting) handler (eventi, ma quando esattamente?

In pagina 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>

Grazie

EDIT:

  

Se è un postback, tuttavia, tali parametri avranno caricato da un ViewState sul OnLoadComplete della pagina, ancora una volta, nell'ordine in cui sono dichiarati.   

Q1 - Supponiamo ControlParameter è legato alla proprietà di un C1 C. di controllo Immagino che il postback ControlProperty sarebbe sempre in grado di ottenere il valore di C.C1 ViewState, non importa di quale tipo C è, e anche se C ha ViewState disabilitato ?!

Q2 - Ma posso chiedere perché, se si crea una pagina per la prima volta, non può un valore per ControlParameter anche essere recuperate ViewState? Dopotutto, i lstCities momento recupera i dati da fonte di dati, lstCities.SelectedValue ha fissato il suo valore?


thanx compagno

SECONDO EDIT:

Mi scuso per non aver risposto prima, ma non mi ero reso conto che hai risposto. E quando l'ho fatto, ho passato buona 20 minuti cercando di ottenere i miei 3 braincells per funzionare correttamente, ma non sono sicuro se ho abbastanza riuscito

A) Così ControlParameter valuta le C.C1 e recupera in tal modo il valore di C.C1 dopo C è stato legato?!

  

Q1 - ControlParameter legge solo il proprio stato e solo per determinare se è cambiato

A) controlli, in modo ControlParameter se la sua ViewState cambiato (in ordine di sparare evento OnParameterChanged) prima avviene il legame -> quindi controlla la sua ViewState durante Page.OnLoadComplete. Ma come farà ControlParameter sapere che la sua ViewState è cambiato (si saprà il primo postback)? Dopotutto, dalla prima volta che la pagina viene creata ViewState di ControlParameter sarà sempre contrassegnato come sporca, così come sarà, da un postback ad un altro, ControlParameter sapere se il suo valore è cambiato tra i postback?

B) Presumo controlli ControlParameter se la sua ViewState cambiato solo in modo che si può sparare evento OnParameterChanged. Ma perché sta gestendo questo evento così importante?

  

La prima volta una valutazione struttura accade è in Page.OnLoadComplete

Per la valutazione di proprietà vuoi dire ControlParameter controllando il proprio ViewState? Così non si intende valutare ControlParameter C.C1 (che presumo accade dopo C è stata vincolata)

Apprezzo molto il vostro aiuto

EDIT TERZO:

Mi dispiace davvero per prendere di nuovo il tuo time.I farà del mio meglio per rendere questo mio ultimo Modifica.

Update () viene chiamato sia in OnLoadComplete e quando l'associazione di dati avviene. All'interno Update () viene eseguita anche la seguente frase:

this.ViewState["ParameterValue"] = actualValue;

Quindi, se Update () viene chiamato quando si svolge l'associazione di dati, allora ciò significa  che quando il prossimo postback UpDate () è chiamato in OnLoadComplete, C.C1 e ControlParameter avranno già stessi valori e quindi

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

restituirà sempre false (quando Update () viene chiamato in OnLoadComplete), e l'evento in modo OnParameterChanged non sarà mai sparato? 1 Se è così, il non riesco a vedere la necessità di chiamare Update () in OnLoadComplete!

molto obbligato

È stato utile?

Soluzione

La prima ipotesi è corretta.

Per la seconda domanda, dipende dal fatto che si tratta di un palo o meno e / o se si sono vincolanti in modo esplicito. Se non è secondo palo e vincolante avviene automaticamente quindi, grosso modo, il valore del ControlParameter viene recuperato quando DataSourceView Chiamate selezionare il DataBind, a destra prima dell'evento OnSelecting. La sequenza per la gridview (e qualsiasi controllo per questo) è il seguente:

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

Quindi, per ogni controllo in una gerarchia di controllo, il quadro chiama ricorsivamente DataBind, che poi innesca il recupero dei parametri, OnSelecting, recupero dei dati, e OnSelected.

Se è un postback, tuttavia, tali parametri avranno caricate da un ViewState sul OnLoadComplete della pagina, ancora una volta, nell'ordine in cui sono dichiarati.

E 'questo quello che cercavi?

Modifica

  

Q1 - Supponiamo ControlParameter è legato alla proprietà di un C1 C. di controllo Immagino che il postback ControlProperty sarebbe sempre in grado di ottenere il valore di C.C1 ViewState, non importa di quale tipo C è, e anche se C ha disattivato ViewState?!

Questo non è del tutto come succede ... Su palo (e su richiesta iniziale è per questo), stato di visualizzazione di ControlParemeter viene valutata solo per vedere se è cambiato in modo che l'evento OnParameterChanged potrebbe ottenere licenziato. Il valore effettivo della ControlParameter viene valutata contro il comando a cui punta (tramite riflessione). Nel tuo caso sarebbe "C.C1". Ora, quando si legge C.C1, il suo valore è molto probabilmente letto da uno stato di visualizzazione. Ma in nessun punto la ControlParameter letto direttamente lo stato di visualizzazione di C.

  

Q2 - Ma posso chiedere perché, se si crea una pagina per la prima volta, non può un valore per ControlParameter anche essere recuperate ViewState? Dopotutto, i lstCities momento recupera i dati da fonte di dati, lstCities.SelectedValue ha fissato il suo valore?

Questa è la cosa, a quel punto (la prima pagina di tempo carichi) i lstCities non recuperare ancora i dati. La prima volta che una valutazione di proprietà accade è il Page.OnLoadComplete, ma prima di qualsiasi DataBind (che avviene poco dopo, quando Page.PreRenderRecursiveInternal viene licenziato).

Nella forma grezza, cercando di metterla in un ciclo di vita di una pagina:

...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

Secondo Modifica

  

Quindi ControlParameter valuta le C.C1 e recupera in tal modo il valore di C.C1 dopo C è stato legato?!

Il ControlParameter recupera i valori ogni volta che si chiede, che in questo scenario si verifica (indirettamente) in due luoghi: OnLoadComplete e DataBind (innescato da PreRenderRecursiveInternal). Sul OnLoadComplete, il C non è vincolata. Su PreRenderRecursiveInternal, dopo DataBind, la C è legato. Entrambe le volte ControlParameter è chiesto di leggere C.C1. Forse in seguito aiuterà ...

Ecco le classi e metodi di interesse in poche parole. Metterli in prospettiva del ciclo di pagina e speriamo che sia chiaro.

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) controlli, in modo ControlParameter se la sua ViewState cambiato ...

Fare riferimento al metodo UpdateValue sopra per vedere come si utilizza ViewState.

  
    

B) Presumo controlli ControlParameter se la sua ViewState cambiato solo in modo che si può sparare evento OnParameterChanged. Ma perché sta gestendo questo evento così importante?

  

Non so che è importante. Suppongo che, come ogni altro evento, che consente di tenere traccia cambiamenti nelle proprietà del parametro e agire di conseguenza alle proprie esigenze. Esso viene licenziato in molti luoghi, ma non vedo dove chiunque sottoscrive ad esso. Quindi ...

  

Per la valutazione di proprietà vuoi dire ControlParameter controllando il proprio ViewState? Così non si intende valutare ControlParameter C.C1 (che presumo che accade dopo C ha been legato)

Ciò significa che il ControlParameter.UpdateValue viene chiamato, che controlla ViewState per ragioni esposte, quindi chiama ControlParameter.Evalue, che poi trova un controllo e recupera i dati utilizzando la riflessione (Eval). Vedi sopra.

Terzo Modifica

Presumo che da Update intendi UpdateValue.

  

Quindi, se Update () viene chiamato quando l'associazione di dati avviene, allora che cosa significa è che quando il prossimo postback Update () viene chiamato in OnLoadComplete, C.C1 e ControlParameter avrà già stessi valori ...

Non necessario. Si sta dimenticando che lo stato di visualizzazione viene caricato sul LoadAllState e tra essa e l'OnLoadComplete ci sono più di sei gradini (vedi pagina del ciclo di vita sopra). Ciascuno di questi possono modificare il valore del controllo sorgente (C.C1).

Diciamo che avete C.C1 = "x" e ha fatto un post indietro. Ora, lo stato di visualizzazione per tutti i controlli è caricato (LoadAllState). Se C.C1 conservato il suo valore nello stato di visualizzazione, caricherà "x". Su Page_Load (LoadRecursive) si decide di impostare C.C1 = "y". Qui C.C1 può decidere di archiviare "y" nel suo stato di visualizzazione o no - è irrilevante. Poi altri eventi seguono. Segue OnLoadComplete. Dal momento che SqlDataSource aderisce a questo evento, che valuterà tutti i parametri associati (LoadCompleteEventHandler) e, dal momento che è stato modificato, ma C.C1 stato di visualizzazione di ControlParameter no, il

if ((actualValue == null && storedValue != null)
 || (actualValue != null && actualValue != storedValue))
    this.OnParameterChanged();

restituirà vero e OnParameterChanged verrà licenziato. Tra l'altro, v'è almeno altri dieci luoghi in cui viene attivato questo evento. Essa non gioca ruolo importante (se presente) in associazione dati e processo di recupero di proprietà.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top