Wenn Steuerelemente sind immer gebunden an Datenquellen-Steuerelemente in der Reihenfolge, wie Sie deklariert sind, dann
-
05-09-2019 - |
Frage
A) Frage basiert auf der Annahme, dass die Kontrollen sind immer gebunden an Datenquellen-Steuerelemente in der Reihenfolge, wie Sie deklariert sind?Also in unserem Beispiel SqlDataSource1 wird eine Verbindung zu Datenquelle vor SqlDataSource2 und damit lstCities werden mit Werten gefüllt, bevor GridView1, und Grund dafür ist, dass lstcities erklärt wurde, vor GridView1?!
B) Wenn ja, dann Wann genau funktioniert ControlParameter ruft einen Wert aus DropDownList?Ich gehe davon aus, dass es nach SqlDataSource1_Selected() event-handler und vor SqlDataSource2_Selecting() event-handler, aber Wann genau?
In .aspx-Seite:
<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>
vielen Dank
EDIT:
Wenn es ein postback, doch dann diejenigen Parameter geladen, die von einem viewstate auf der Seite OnLoadComplete, wieder in der Reihenfolge in der Sie deklariert sind.
Q1 - nehmen wir mal ControlParameter gebunden ist, die Eigenschaft C1 des control-C.Ich könnte mir vorstellen, dass auf postbacks ControlProperty würden immer in der Lage zu bekommen, C. C1, die den Wert von ViewState, egal welcher Typ C ist, und auch, wenn C ViewState deaktiviert?!
Q2 - Aber darf ich Fragen, warum, wenn eine Seite erstellt für die erste Zeit, nicht den Wert für ControlParameter auch abgerufen werden von viewstate?Afterall, der moment lstCities ruft Daten aus der Datenquelle, lstCities.SelectedValue hat seinen Wert eingestellt?
thanx mate
ZWEITER EDIT:
Ich entschuldige mich für die Beantwortung nicht früher, aber ich wusste nicht, dass Sie geantwortet haben.Und als ich das Tat, habe ich gute 20 Minuten versucht, meine 3 braincells, um richtig zu arbeiten, aber ich bin mir nicht sicher, ob ich Recht gelungen
A) So ControlParameter wertet C. C1 und so ruft C. C1, die den Wert nach C gebunden wurde?!
Q1 - ControlParameter liest nur seinen eigenen Staat und nur, um festzustellen, ob es geändert
A) So ControlParameter prüft, ob Ihre ViewState geändert ( um das Feuer OnParameterChanged Ereignis) vor Bindung erfolgt --> damit es überprüft seine ViewState bei Seite.OnLoadComplete.Aber wie wird ControlParameter wissen, dass Ihre ViewState geändert hat ( es wird wissen, auf den ersten postback )?Afterall, vom ersten mal, wenn die Seite erstellt wird ControlParameter ViewState wird immer als fehlerhaft markiert, so wie werden, von einem postback zu einem anderen, ControlParameter wissen, ob der Wert sich geändert hat zwischen postbacks?
B) ich nehme an, ControlParameter prüft, ob Ihre Viewstate nur geändert, so dass es kann Feuer OnParameterChanged Ereignis.Aber warum ist der Umgang mit, dass die Veranstaltung so wichtig?
Das erste mal eine Bewertung von Liegenschaften geschieht, ist auf der Seite.OnLoadComplete
Durch die Bewertung von Liegenschaften du meinst ControlParameter die überprüfung seiner eigenen ViewState?Damit Sie nicht bedeuten, ControlParameter Bewertung C. C1 ( was ich davon ausgehen ist passiert, nachdem C gebunden wurde )
Ich wirklich schätzen Ihre Hilfe
DRITTE ÄNDERUNG:
Ich bin wirklich sorry für die wieder nehmen Ihre Zeit.Ich werde mein bestes tun, um dies meine Letzte änderung.
Update() wird aufgerufen, sowohl in OnLoadComplete und wenn die Datenbindung erfolgt.Insider Update() der folgende Satz wird auch ausgeführt:
this.ViewState["ParameterValue"] = actualValue;
So if Update() wird aufgerufen, wenn Daten Bindung stattfindet, dann ist das, was das bedeutet, ist dass, wenn auf der nächsten postback UpDate() wird aufgerufen, in OnLoadComplete, C. C1 und ControlParameter bereits die gleichen Werte und damit
if ((actualValue == null && storedValue != null)
|| (actualValue != null && actualValue != storedValue))
wird immer false zurückgeben ( wenn Sie Update() wird aufgerufen, in OnLoadComplete ), und so OnParameterChanged-Ereignis wird nie ausgelöst?1 Wenn das so ist, das ich nicht sehen die Notwendigkeit, rufen Sie Update() in OnLoadComplete!
viel verpflichtet
Lösung
Ihre erste Vermutung ist richtig.
Zu deiner zweiten Frage, es hängt davon ab, ob es ein post zurück oder nicht und/oder wenn Sie explizit verbindlich.Wenn es ist nicht die post zurück und die Bindung erfolgt automatisch dann, grob gesprochen, den Wert der ControlParameter wird abgerufen, wenn DataSourceView Anrufe Wählen Sie auf DataBind, direkt vor OnSelecting Ereignis.Die Reihenfolge für die gridview (und Kontrolle, für diese Angelegenheit) ist wie folgt:
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
Also, für jedes Steuerelement ein Steuerelement Hierarchie, das framework ruft rekursiv DataBind, die löst dann den Abruf von Parametern, OnSelecting, abrufen von Daten, und OnSelected.
Wenn es ein postback, doch dann diejenigen Parameter geladen, die von einem viewstate auf der Seite OnLoadComplete, wieder in der Reihenfolge in der Sie deklariert sind.
Ist es das, was Sie gesucht haben?
Bearbeiten
Q1 - nehmen wir mal ControlParameter gebunden ist, die Eigenschaft C1 des control-C.Ich könnte mir vorstellen, dass auf postbacks ControlProperty würden immer in der Lage zu bekommen, C. C1, die den Wert von ViewState, egal welcher Typ C ist, und auch, wenn C ViewState deaktiviert?!
Das ist so nicht ganz, wie es passiert...Auf post zurück (und auf erste Anforderung für diese Angelegenheit), ControlParemeter Ansicht Zustand ausgewertet wird, nur um zu sehen, ob es so geändert, dass die OnParameterChanged Ereignis könnte gefeuert.Der tatsächliche Wert des ControlParameter evaluiert wird, die es kontrollieren, Punkte zu (per reflection).In Ihrem Fall wäre es "C. C1".Nun, wenn es liest, C. C1, dessen Wert wahrscheinlich Lesen von einem Ansichtsstatus.Aber an keiner Stelle tut der ControlParameter Lesen Sie C ' s view Staat direkt.
Q2 - Aber darf ich Fragen, warum, wenn eine Seite erstellt für die erste Zeit, nicht den Wert für ControlParameter auch abgerufen werden von viewstate?Afterall, der moment lstCities ruft Daten aus der Datenquelle, lstCities.SelectedValue hat seinen Wert eingestellt?
Das ist die Sache, an diesem Punkt (das erste mal die Seite geladen ist) das lstCities haben keine Daten abgerufen noch.Das erste mal eine Bewertung von Liegenschaften geschieht, ist auf der Seite.OnLoadComplete, aber vor allen DataBind (was passiert kurz danach, Wann die Seite.PreRenderRecursiveInternal gefeuert wird).
In der rohen form, versuchen zu Ort es in einem Lebenszyklus einer Seite:
...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
Zweiter Edit
So ControlParameter wertet C. C1 und so ruft C. C1, die den Wert nach C gebunden wurde?!
Die ControlParameter ruft die Werte, wenn es um die Frage, die in diesem Szenario passiert (indirekt) an zwei stellen:OnLoadComplete und DataBind (ausgelöst durch PreRenderRecursiveInternal).Auf OnLoadComplete, die C ist nicht gebunden.Auf PreRenderRecursiveInternal, nach DataBind, die C gebunden ist.Beide Male ControlParameter ist gefragt, um zu Lesen C. C1.Vielleicht folgenden wird dazu beitragen,...
Hier sind die Klassen und Methoden von Interesse in einer nussschale.Legen Sie Sie in der Perspektive von der Seite, Zyklus und wird es hoffentlich klar.
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) So ControlParameter prüft, ob Ihre ViewState geändert...
Finden Sie die UpdateValue Methode oben, um zu sehen, wie es verwendet ViewState.
B) ich nehme an, ControlParameter prüft, ob Ihre Viewstate nur geändert, so dass es kann Feuer OnParameterChanged Ereignis.Aber warum ist der Umgang mit, dass die Veranstaltung so wichtig?
Ich weiß nicht, dass es wichtig ist.Ich nehme an, wie bei jedem anderen Ereignis, es ermöglicht die Nachverfolgung von änderungen in parameter Eigenschaften und entsprechend handeln, um Ihre Bedürfnisse.Es gefeuert wird an vielen Orten, aber ich sehe nicht, wo jemand abonniert Sie.So...
Durch die Bewertung von Liegenschaften du meinst ControlParameter die überprüfung seiner eigenen ViewState?Damit Sie nicht bedeuten, ControlParameter Bewertung C. C1 ( was ich davon ausgehen ist passiert, nachdem C gebunden wurde )
Es bedeutet, dass die ControlParameter.UpdateValue wird aufgerufen, die prüft, ViewState für den genannten Gründen, dann ruft ControlParameter.Evalue, welche dann findet eine Steuerung und ruft die Daten mithilfe von Reflexion (Eval).Siehe oben.
Dritte Bearbeiten
Ich vermute, dass durch das Update du meinst UpdateValue.
So if Update() wird aufgerufen, wenn Daten Bindung erfolgt, dann was das bedeutet ist, dass, wenn auf der nächsten postback UpDate() wird aufgerufen, in OnLoadComplete, C. C1 und ControlParameter bereits die gleichen Werte...
Nicht notwendig.Sie vergessen, dass der Ansichtsstatus wird geladen LoadAllState und zwischen ihm und dem OnLoadComplete gibt es noch sechs Schritte (siehe Seite life-cycle oben).Jeder von denen kann ändern Sie die source-control-s (C. C1) Wert.
Sagen Sie C. C1 = "x" und habe eine Stelle zurück.Nun, die Ansichtszustand für alle Steuerelemente geladen ist (LoadAllState).Wenn C. C1 gespeichert, die es Wert ist, in der Ansicht Zustand, es wird geladen "x".Auf Page_Load (LoadRecursive) Sie sich entschließen, C. C1 = "y".Hier C. C1 können entscheiden, zu speichern "y" seiner Ansicht nach Staat oder nicht-es ist irrelevant.Dann andere Ereignisse Folgen.Als Nächstes kommt OnLoadComplete.Seit SqlDataSource abonniert diesem Fall, es wertet alle zugehörigen Parameter (LoadCompleteEventHandler) und, da Sie noch ändern, C. C1, aber ControlParameter Ansicht Staat nicht, die
if ((actualValue == null && storedValue != null)
|| (actualValue != null && actualValue != storedValue))
this.OnParameterChanged();
wird true zurückgegeben und OnParameterChanged gefeuert wird.Übrigens, es gibt mindestens zehn andere Orte, wo dieses Ereignis wird ausgelöst.Es spielt keine große Rolle spielen (wenn überhaupt) in der Datenbindung und Eigentum retrieval-Prozess.