Si les contrôles sont toujours binded aux contrôles de source de données dans l'ordre dans lequel ils sont déclarés alors

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

Question

A) Question ci-dessous est basée sur l'hypothèse que les contrôles sont toujours binded aux contrôles de source de données dans l'ordre dans lequel ils sont déclarés? Ainsi, dans notre exemple SqlDataSource1 se connecte à une source de données avant SqlDataSource2 et donc lstCities sera peuplé de valeurs avant de GridView1 , et la raison de cet être que lstcities a été déclaré avant GridView1 !


B) Si oui, alors quand est exactement ControlParameter récupérer une valeur de DropDownList ? Je suppose que c'est après SqlDataSource1_Selected () gestionnaire d'événements et avant SqlDataSource2_Selecting () gestionnaire d'événements, mais quand précisément?

Dans la page .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

EDIT:

  

S'il est un postback, cependant, alors ces paramètres vont se charger d'un état d'affichage sur OnLoadComplete, encore une fois de la page, dans l'ordre où ils sont déclarés.   

Q1 - Supposons que ControlParameter est lié à la propriété C1 d'un C. témoin Je suppose que le postbacks ControlProperty serait toujours en mesure d'obtenir la valeur de C.C1 de ViewState, peu importe de quel type C est, et même si C a ViewState désactivé ?!

Q2 - Mais puis-je demander pourquoi, si une page est créée pour la première fois, ne peut pas une valeur pour ControlParameter également être récupéré à partir de ViewState? Après tout, les lstCities de moment extrait les données de la source de données, lstCities.SelectedValue a sa valeur définie?


mate thanx

DEUXIÈME EDIT:

Je suis désolé de ne pas avoir répondu plus tôt, mais je ne vous ai pas réalisé avez répondu. Et quand je l'ai fait, je l'ai passé un bon 20 minutes à essayer d'obtenir mes 3 méninges pour fonctionner correctement, mais je ne suis pas sûr si je tout à fait réussi

A) Alors ControlParameter et évalue C.C1 récupère ainsi la valeur de C.C1 après C est lié!

  

Q1 - ControlParameter ne lit que son propre état et seulement pour déterminer si elle a changé

A) vérifie donc ControlParameter si son ViewState a changé (pour le feu événement OnParameterChanged) avant de se lier a lieu -> donc il vérifie son ViewState pendant Page.OnLoadComplete. Mais comment saura ControlParameter que son ViewState a changé (il connaîtra le premier postback)? Après tout, de la première fois que la page est créé le ViewState ControlParameter sera toujours aussi sale marqué, donc comment, d'un postback à l'autre, ControlParameter savoir si sa valeur a changé entre postbacks?

B) Je suppose que les contrôles ControlParameter si son Viewstate a changé seulement pour qu'il puisse tirer événement OnParameterChanged. Mais pourquoi est la manipulation de cet événement si important?

  

La première fois une évaluation de la propriété se trouve sur Page.OnLoadComplete

Par l'évaluation de la propriété que vous voulez dire ControlParameter vérifier sa propre ViewState? Ainsi, vous ne voulez pas ControlParameter évaluer C.C1 (que je suppose que se passe après C a été lié)

Je vous remercie de votre aide

TROISIÈME EDIT:

Je suis vraiment désolé de prendre à nouveau votre time.I fera de mon mieux pour faire mon dernier Edition.

Mise à jour () est appelée à la fois dans OnLoadComplete et quand la liaison de données a lieu. A l'intérieur de mise à jour () la phrase suivante est également exécutée:

this.ViewState["ParameterValue"] = actualValue;

Donc, si Update () est appelée lorsque la liaison de données se produit, alors ce que cela signifie est  que lorsque le prochain postback UpDate () est appelée à OnLoadComplete, C.C1 et ControlParameter aura déjà les mêmes valeurs et donc

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

retournera toujours faux (quand Update () est appelée à OnLoadComplete), et l'événement afin OnParameterChanged ne sera jamais tiré 1? Si oui, le je ne vois pas la nécessité d'appeler mise à jour () dans OnLoadComplete!

bien obligé

Était-ce utile?

La solution

Votre première hypothèse est correcte.

Pour votre deuxième question, cela dépend si elle est un poste de retour ou non, et / ou si vous liez explicitement. Si ce n'est pas le poste arrière et la liaison se fait automatiquement alors, grosso modo, la valeur de la ControlParameter est récupérée lorsque les appels DataSourceView Sélectionnez le DataBind, juste avant l'événement OnSelecting. La séquence du gridview (et toute commande donnée pour cette matière) est la suivante:

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

Ainsi, pour chaque contrôle dans une hiérarchie de contrôle, le cadre appelle récursive DataBind, qui déclenche alors la récupération des paramètres, OnSelecting, la récupération de données et OnSelected.

S'il est un postback, cependant, alors ces paramètres seront chargés à partir d'un se viewstate à nouveau OnLoadComplete de la page, dans l'ordre où ils sont déclarés.

Est-ce que vous cherchez?

Modifier

  

Q1 - Supposons que ControlParameter est lié à la propriété C1 d'un C. témoin Je suppose que le postbacks ControlProperty serait toujours en mesure d'obtenir la valeur de C.C1 de ViewState, peu importe de quel type C est, et même si C a ViewState désactivé!

Ce n'est pas tout à fait comment ça se passe ... Le message de retour (et sur demande initiale de cette question), l'état d'affichage de ControlParemeter est évaluée uniquement pour voir si elle a changé de sorte que l'événement OnParameterChanged pourrait être licenciée. La valeur réelle de la ControlParameter est évaluée par rapport à la commande pointe vers (par réflexion). Dans votre cas, il serait « C.C1 ». Maintenant, quand il lit C.C1, sa valeur est très probablement lu à partir d'un état d'affichage. Mais à aucun moment la lecture ControlParameter état d'affichage de C directement.

  

Q2 - Mais puis-je demander pourquoi, si une page est créée pour la première fois, ne peut pas une valeur pour ControlParameter également être récupéré à partir de ViewState? Après tout, les lstCities de moment extrait les données de la source de données, lstCities.SelectedValue a sa valeur définie?

C'est la chose, à ce moment-là (la première page se charge de temps) les lstCities ne récupèrent pas encore les données. La première fois une évaluation de la propriété se trouve sur Page.OnLoadComplete, mais avant tout DataBind (ce qui arrive peu après, quand Page.PreRenderRecursiveInternal est congédié).

Dans la forme brute, en essayant de le placer dans un cycle de vie d'une page:

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

Second Edition

  

ControlParameter et récupère C.C1 évalue ainsi la valeur de C.C1 après C est lié!

Le ControlParameter récupère les valeurs chaque fois qu'il est demandé, qui dans ce scénario se produit (indirectement) en deux endroits: OnLoadComplete et DataBind (déclenchée par PreRenderRecursiveInternal). Sur OnLoadComplete, le C est pas lié. Sur PreRenderRecursiveInternal, après DataBind, le C est lié. Les deux fois ControlParameter est invité à lire C.C1. suivants vous aideront peut-être ...

Voici les classes et méthodes d'intérêt en un mot. Placez-les dans la perspective du cycle de la page et nous espérons qu'il sera clair.

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) vérifie donc ControlParameter si son ViewState a changé ...

Reportez-vous à la méthode UpdateValue ci-dessus pour voir comment il utilise ViewState.

  
    

B) Je suppose que les contrôles ControlParameter si son Viewstate a changé seulement pour qu'il puisse tirer événement OnParameterChanged. Mais pourquoi est la manipulation de cet événement si important?

  

Je ne sais pas qu'il est important. Je suppose que, comme tout autre événement, il vous permet de suivre les changements dans les propriétés de paramètres et d'agir en fonction de vos besoins. Il est congédié dans de nombreux endroits, mais je ne vois pas où tout le monde y souscrit. Alors ...

  

Par l'évaluation de la propriété que vous voulez dire ControlParameter vérifier sa propre ViewState? Ainsi, vous ne voulez pas ControlParameter évaluer C.C1 (que je suppose que se passe après C a been lié)

Cela signifie que le ControlParameter.UpdateValue est appelé, qui vérifie ViewState pour les raisons indiquées, puis appelle ControlParameter.Evalue, qui trouve ensuite un contrôle et récupère les données en utilisant la réflexion (Eval). Voir ci-dessus.

Troisième Edition

Je suppose que par mise à jour vous dire UpdateValue.

  

Donc, si Update () est appelée lorsque la liaison de données a lieu, alors ce que cela signifie est que lorsque le prochain postback UpDate () est appelée à OnLoadComplete, C.C1 et ControlParameter aura déjà les mêmes valeurs ...

Non nécessaire. Vous oubliez que l'état d'affichage est chargé sur LoadAllState et entre elle et le OnLoadComplete il y a six autres étapes (voir page cycle de vie ci-dessus). Chacun de ceux-ci peuvent modifier (C.C1) la valeur de la commande de la source.

Disons que vous avez C.C1 = "x" et a fait un poste arrière. Maintenant, l'état d'affichage pour tous les contrôles est chargé (LoadAllState). Si C.C1 stocké sa valeur dans l'état d'affichage, il charge « x ». Sur Page_Load (LoadRecursive) vous décidez de mettre C.C1 = "y". Ici C.C1 peut décider de stocker « y » dans son état d'affichage ou non - il est hors de propos. Ensuite, d'autres événements suivent. Vient ensuite OnLoadComplete. Depuis SqlDataSource souscrit à cet événement, il évaluera tous les paramètres associés (LoadCompleteEventHandler) et, puisque vous avez modifié C.C1, mais l'état d'affichage de ControlParameter n'a pas, le

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

retourne vrai et OnParameterChanged sera tiré. Soit dit en passant, il y a au moins dix autres endroits où cet événement se déclenche. Il ne joue pas grand rôle (le cas échéant) dans la liaison de données et le processus de récupération de la propriété.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top