Se os controles são sempre binded a controles de fonte de dados na ordem em que são declaradas, em seguida,

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

Pergunta


A) Pergunta abaixo é baseada na suposição de que os controles estão sempre binded a controles de fonte de dados na ordem em que são declarados? Assim, em nosso exemplo SqlDataSource1 irá se conectar a fonte de dados antes de SqlDataSource2 e, portanto, lstCities será preenchida com valores antes de GridView1 , ea razão para isso é que lstcities foi declarada antes de GridView1 ?!


B) Em caso afirmativo, em seguida, quando faz exatamente ControlParameter recuperar um valor de DropDownList ? Eu supor que é depois de SqlDataSource1_Selected () manipulador de eventos e antes SqlDataSource2_Selecting () manipulador de eventos, mas quando exatamente?

Na página .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:

Se for uma nova postagem, no entanto, em seguida, os parâmetros vai ser carregado a partir de um estado de visualização na página do OnLoadComplete, mais uma vez, na ordem em que são declaradas.

Q1 - Vamos supor ControlParameter é obrigado a C1 propriedade de um controle C. Eu imaginaria que em postbacks ControlProperty seria sempre capaz de obter o valor de C.C1 de ViewState, não importa de que tipo C é, e mesmo se C tem ViewState desativada ?!

Q2 - Mas posso perguntar por que, se uma página é criada pela primeira vez, pode não um valor para ControlParameter também ser recuperado a partir viewstate? Afinal, os dados lstCities momento recupera da fonte de dados, lstCities.SelectedValue tem seu valor definido?


thanx companheiro


SEGUNDO EDIT:

Peço desculpas por não responder mais cedo, mas eu não sabia que você já respondeu. E quando o fiz, passei boa 20 minutos a tentar obter meus 3 braincells para funcionar corretamente, mas não tenho certeza se eu bem sucedido


A) Assim ControlParameter avalia C.C1 e, assim, recupera o valor da C.C1 depois C foi ligado?!


Q1 - ControlParameter só lê seu próprio estado e só para determinar se ele mudou

cheques A) Assim ControlParameter se o seu ViewState alterado (a fim de fogo OnParameterChanged evento) antes de ligação ocorre -> assim, ele verifica sua ViewState durante Page.OnLoadComplete. Mas como ControlParameter saber que sua ViewState mudou (ele vai saber em primeira postagem)? Afinal, desde a primeira vez que a página é criada ViewState do ControlParameter será sempre marcado como sujo, então como é que, de um postback para o outro, ControlParameter saber se o seu valor mudou entre postbacks?

B) Presumo cheques ControlParameter se o seu Viewstate alterado apenas para que ele possa disparar evento OnParameterChanged. Mas por que está a lidar com esse evento tão importante?


A primeira vez que uma avaliação da propriedade acontece é em Page.OnLoadComplete

Por avaliação da propriedade você quer dizer ControlParameter verificando seu próprio ViewState? Assim você faz ControlParameter não média avaliar C.C1 (que eu suponho que acontece depois C foi ligado)


Eu realmente aprecio a sua ajuda


EDIT TERCEIRO:

Eu realmente sinto muito por mais uma vez tomar o seu time.I farei o meu melhor para fazer este meu último Editar.


Update () é chamado tanto em OnLoadComplete e quando a ligação de dados ocorre. Dentro Update () a seguinte frase também é executado:

this.ViewState["ParameterValue"] = actualValue;

Então, se Update () é chamado quando a ligação de dados ocorre, então o que isso significa é que, quando no próximo update postback () é chamado em OnLoadComplete, C.C1 e ControlParameter já terá mesmos valores e, portanto,

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

sempre retornará false (quando Update () é chamado em OnLoadComplete), e evento para OnParameterChanged nunca vai ser demitido? 1 Se assim for, o que não conseguem ver a necessidade de chamar Update () em OnLoadComplete!


muito obrigado

Foi útil?

Solução

Sua primeira suposição é correta.

Para sua segunda pergunta, depende se é um post de volta ou não e / ou se estiver a vincular explicitamente. Se não for parte de trás pós e vinculativa acontece automaticamente, em seguida, a grosso modo, o valor do ControlParameter é recuperada quando DataSourceView chama Select no DataBind, logo antes do evento OnSelecting. A sequência para o gridview (e qualquer dado de controlo para esse efeito) é como se segue:

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

Assim, para cada controle em uma hierarquia de controle, o quadro chama recursivamente DataBind, que então desencadeia recuperação de parâmetros, OnSelecting, recuperação de dados, e OnSelected.

Se for uma nova postagem, no entanto, em seguida, os parâmetros vai ser carregado a partir de um estado de visualização na página do OnLoadComplete, mais uma vez, na ordem em que são declaradas.

É isso que você estava procurando?

Editar

Q1 - Vamos supor ControlParameter é obrigado a C1 propriedade de um controle C. Eu imaginaria que em postbacks ControlProperty seria sempre capaz de obter o valor de C.C1 de ViewState, não importa de que tipo C é, e mesmo se C tem ViewState desabilitado?!

Isso não é inteiramente como isso acontece ... Na parte traseira pós (e no pedido inicial para que o assunto), o estado de exibição de ControlParemeter só é avaliada para ver se ele mudou para que o evento OnParameterChanged poderia ser demitido. O valor real do ControlParameter é avaliada contra o controlo que aponta para (por meio de reflexo). No seu caso seria "C.C1". Agora, quando se lê C.C1, seu valor é mais provável ler a partir de um estado de exibição. Mas em nenhum momento faz o ControlParameter ler o estado de exibição do C diretamente.

Q2 - Mas posso perguntar por que, se uma página é criada pela primeira vez, pode não um valor para ControlParameter também ser recuperado a partir viewstate? Afinal, os dados lstCities momento recupera da fonte de dados, lstCities.SelectedValue tem seu valor definido?

Essa é a coisa, naquele momento (as primeiras cargas de página tempo) os lstCities não recuperar todos os dados ainda. A primeira vez que uma avaliação da propriedade acontece é em Page.OnLoadComplete, mas antes de qualquer DataBind (o que acontece pouco depois, quando Page.PreRenderRecursiveInternal é demitido).

Na forma bruta, tentando colocá-lo em um ciclo de vida de uma página:

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

Segunda Editar

Assim ControlParameter avalia C.C1 e, assim, recupera o valor da C.C1 depois C foi ligado?!

Os valores Recupera ControlParameter sempre que for solicitado, que neste cenário acontece (indiretamente) em dois locais: OnLoadComplete e DataBind (desencadeada por PreRenderRecursiveInternal). Em OnLoadComplete, o C não estiver ligada. Em PreRenderRecursiveInternal, após DataBind, o C está ligado. Ambas as vezes ControlParameter é solicitado a ler C.C1. Talvez seguir ajudará ...

Aqui estão as classes e métodos de interesse em poucas palavras. Coloque-os em perspectiva do ciclo de página e espero que seja clara.

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

cheques A) Assim ControlParameter se o seu ViewState mudou ...

Consulte o método UpdateValue acima para ver como ele usa ViewState.

B) Presumo cheques ControlParameter se o seu Viewstate alterado apenas para que ele possa disparar evento OnParameterChanged. Mas por que está a lidar com esse evento tão importante?

Eu não sei que é importante. Suponho que, como qualquer outro evento, ele permite que você acompanhe mudanças nas propriedades de parâmetros e agir em conformidade com as suas necessidades. Ele é demitido em muitos lugares, mas eu não vejo onde ninguém subscreve a ele. Então ...

Por avaliação da propriedade você quer dizer ControlParameter verificando seu próprio ViewState? Assim você faz ControlParameter não média avaliar C.C1 (que eu suponho que acontece depois C tem been bound)

Isso significa que o ControlParameter.UpdateValue é chamado, que verifica ViewState razões expostas, em seguida, chama ControlParameter.Evalue, que, em seguida, encontra um controle e recupera dados usando reflexão (Eval). Veja acima.

Third Editar

Eu presumo que por Atualização quer dizer UpdateValue.

Então, se Update () é chamado quando a ligação de dados ocorre, então o que isso significa é que, quando a próxima atualização de postagem () é chamado em OnLoadComplete, C.C1 e ControlParameter já terá mesmos valores ...

Não necessário. Você está esquecendo que o estado de exibição é carregado em LoadAllState e entre ele eo OnLoadComplete há mais seis etapas (ver ciclo de vida da página acima). Cada um desses pode modificar o valor do controle de origem (C.C1).

Digamos que você tenha C.C1 = "x" e fez um posto de volta. Agora, o estado de exibição para todos os controlos é carregado (LoadAllState). Se C.C1 armazenado de valor no estado de exibição, ele irá carregar "x". Em Page_Load (LoadRecursive) você decidir definir C.C1 = "y". Aqui C.C1 pode decidir armazenar "y" em seu estado de exibição ou não - é irrelevante. Em seguida, outros eventos seguem. Em seguida, vem OnLoadComplete. Desde SqlDataSource subscreve a este evento, que irá avaliar todos os parâmetros associados (LoadCompleteEventHandler) e, uma vez que você fez a mudança C.C1 mas estado de exibição do ControlParameter não, o

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

retornará verdadeiro e OnParameterChanged será demitido. By the way, há pelo menos dez outros lugares onde este evento é acionado. Ele não joga um papel grande (se houver) na ligação de dados e processo de recuperação de propriedade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top