Если элементы управления всегда привязаны к элементам управления источником данных в том порядке, в котором они объявлены, тогда

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

Вопрос


А) Вопрос ниже основан на предположении, что элементы управления всегда привязаны к элементам управления источниками данных в том порядке, в котором они объявлены?Итак, в нашем примере SqlDataSource1 подключится к источнику данных, предшествующему SqlDataSource2, и, таким образом, lstCities будет заполнен значениями раньше ГридВью1, и причина этого в том, что список городов было объявлено ранее ГридВью1?!



Б) Если да, то когда именно это произойдет? Параметр управления получить значение из Выпадающий список?Я предполагаю, что это после 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>


спасибо

РЕДАКТИРОВАТЬ:

Однако если это обратная передача, то эти параметры будут загружены из состояния просмотра в OnLoadComplete страницы, опять же, в том порядке, в котором они объявлены.

Q1. Предположим, что ControlParameter привязан к свойству C1 элемента управления C.Я предполагаю, что при обратной передаче ControlProperty всегда сможет получить значение C.C1 из ViewState, независимо от того, какой тип C, и даже если C отключил ViewState?!

Вопрос 2. Могу ли я спросить, почему, если страница создается впервые, значение ControlParameter также не может быть получено из состояния просмотра?В конце концов, в тот момент, когда lstCities извлекает данные из источника данных, lstCities.SelectedValue устанавливает свое значение?



спасибо, приятель


ВТОРОЕ РЕДАКТИРОВАНИЕ:

Прошу прощения, что не ответил раньше, но я не заметил, что вы ответили.И когда я это сделал, я потратил добрых 20 минут, пытаясь заставить мои три мозговые клетки работать должным образом, но я не уверен, что мне это удалось.


А) Значит, ControlParameter оценивает C.C1 и, таким образом, получает значение C.C1 после привязки C?!


Q1 — ControlParameter считывает только свое состояние и только для того, чтобы определить, изменилось ли оно.

А) Таким образом, ControlParameter проверяет, изменилось ли его ViewState (чтобы вызвать событие OnParameterChanged) до того, как произойдет привязка --> таким образом, он проверяет свое ViewState во время Page.OnLoadComplete.Но как ControlParameter узнает, что его ViewState изменилось (он узнает об этом при первой обратной передаче)?В конце концов, с момента первого создания страницы ViewState ControlParameter всегда будет помечен как «грязный», так как же ControlParameter при переходе от одной обратной передачи к другой узнает, изменилось ли его значение между обратными передачами?

Б) Я предполагаю, что ControlParameter проверяет, изменилось ли его состояние просмотра, только для того, чтобы можно было запустить событие OnParameterChanged.Но почему обработка этого события так важна?


Впервые оценка свойства происходит на Page.OnLoadComplete.

Под оценкой свойства вы имеете в виду ControlParameter, проверяющий собственный ViewState?Таким образом, вы не имеете в виду, что ControlParameter оценивает C.C1 (что, как я предполагаю, происходит после привязки C)


Я действительно ценю твою помощь


ТРЕТЬЕ РЕДАКТИРОВАНИЕ:

Мне очень жаль, что я снова отнял у вас время. Я сделаю все возможное, чтобы сделать это моим последним редактированием.


Update() вызывается как в OnLoadComplete, так и при привязке данных.Внутри Update() также выполняется следующее предложение:

this.ViewState["ParameterValue"] = actualValue;

Таким образом, если update () вызывается, когда происходит привязка данных, то это означает, что когда на следующем Postback Update () вызывается в OnloadComplete, C.C1 и ControlParameter уже будут иметь одинаковые значения и, следовательно

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

всегда будет возвращать false (когда Update() вызывается в OnLoadComplete), и поэтому событие OnParameterChanged никогда не будет запущено? 1 Если да, то я не вижу необходимости вызывать Update() в OnLoadComplete!


Весьма признателен

Это было полезно?

Решение

Ваше первое предположение верно.

Что касается вашего второго вопроса, это зависит от того, является ли это ответным сообщением или нет, и/или если вы явно связываете свои обязательства.Если это не обратная связь и привязка происходит автоматически, то, грубо говоря, значение ControlParameter извлекается, когда DataSourceView вызывает Select в DataBind, прямо перед событием OnSelecting.Последовательность для 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

Таким образом, для каждого элемента управления в иерархии элементов управления платформа рекурсивно вызывает DataBind, который затем запускает получение параметров, OnSelecting, извлечение данных и OnSelected.

Однако если это обратная передача, то эти параметры будут загружены из состояния просмотра в OnLoadComplete страницы, опять же, в том порядке, в котором они объявлены.

Это то, что ты искал?

Редактировать

Q1. Предположим, что ControlParameter привязан к свойству C1 элемента управления C.Я предполагаю, что при обратной передаче ControlProperty всегда сможет получить значение C.C1 из ViewState, независимо от того, какой тип C, и даже если C отключил ViewState?!

Все происходит не совсем так...При ответном сообщении (и при первоначальном запросе в этом отношении) состояние просмотра ControlParemeter оценивается только для того, чтобы увидеть, изменилось ли оно так, чтобы событие OnParameterChanged могло быть запущено.Фактическое значение ControlParameter сравнивается с элементом управления, на который он указывает (посредством отражения).В вашем случае это будет «C.C1».Теперь, когда он читает C.C1, его значение, скорее всего, считывается из состояния просмотра.Но ни в коем случае ControlParameter не считывает состояние представления C напрямую.

Вопрос 2. Могу ли я спросить, почему, если страница создается впервые, значение ControlParameter также не может быть получено из состояния просмотра?В конце концов, в тот момент, когда 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 извлекает значения всякий раз, когда его запрашивают, что в этом сценарии происходит (косвенно) в двух местах: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
        //...
    }
}

А) Итак, ControlParameter проверяет, изменилось ли его ViewState...

Обратитесь к методу UpdateValue выше, чтобы узнать, как он использует ViewState.

Б) Я предполагаю, что ControlParameter проверяет, изменилось ли его состояние просмотра, только для того, чтобы можно было запустить событие OnParameterChanged.Но почему обработка этого события так важна?

Я не знаю, насколько это важно.Полагаю, как и любое другое событие, оно позволяет отслеживать изменения свойств параметра и действовать в соответствии с вашими потребностями.Его запускают во многих местах, но я не вижу, где кто-то на него подписывается.Так...

Под оценкой свойства вы имеете в виду ControlParameter, проверяющий собственный ViewState?Таким образом, вы не имеете в виду, что ControlParameter оценивает C.C1 (что, как я предполагаю, происходит после привязки C)

Это означает, что вызывается ControlParameter.UpdateValue, который проверяет ViewState по указанным причинам, затем вызывает ControlParameter.Evalue, который затем находит элемент управления и извлекает данные с помощью отражения (Eval).См. выше.

Третье редактирование

Я предполагаю, что под обновлением вы имеете в виду UpdateValue.

Таким образом, если Update() вызывается, когда происходит привязка данных, это означает, что при следующем обратном запросе UpDate() вызывается в OnLoadComplete, C.C1 и ControlParameter уже будут иметь одинаковые значения...

Не обязательно.Вы забываете, что состояние представления загружается в LoadAllState и между ним и OnLoadComplete есть еще шесть шагов (см. жизненный цикл страницы выше).Каждый из них может изменить значение системы управления версиями (C.C1).

Допустим, у вас есть C.C1 = «x» и вы отправили ответное сообщение.Теперь состояние просмотра для всех элементов управления загружено (LoadAllState).Если CC1 сохранил свое значение в состоянии просмотра, он загрузит «x».В Page_Load (LoadRecursive) вы решаете установить CC1 = «y».Здесь C.C1 может решить сохранить «y» в своем состоянии просмотра или нет — это не имеет значения.Затем следуют другие события.Далее идет OnLoadComplete.Поскольку SqlDataSource подписывается на это событие, он будет оценивать все связанные параметры (LoadCompleteEventHandler), а поскольку вы изменили C.C1, а состояние представления ControlParameter — нет,

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

вернет true, и OnParameterChanged будет запущен.Кстати, есть еще как минимум десять мест, где срабатывает это событие.Это не играет большой роли (если таковая имеется) в процессе привязки данных и извлечения свойств.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top