문제


a) 아래 질문 아래 질문은 제어가 항상 선언 된 순서대로 데이터 소스 제어에 컨트롤이 묻힌다는 가정에 근거합니다. 따라서이 예에서는 sqldatasource1이 sqldatasource2 이전에 데이터 소스에 연결됩니다. lstcities 전에는 값으로 채워집니다 gridview1, 그 이유는 그 이유입니다 lstcities 전에 선언되었습니다 gridview1?!



b) 그렇다면 정확히 언제 ControlParameter 값을 검색하십시오 드롭 다운 목록? 나는 그것이 후에 있다고 가정합니다 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의 ViewState에서 선언 된 순서대로로드됩니다.

Q1- ControlParameter가 Control C의 속성 C1에 결합되어 있다고 가정합시다 ?!

Q2- 그러나 왜 페이지가 처음으로 작성되었는지 묻는 이유를 물어볼 수 있습니까? ControlParameter의 값도 ViewState에서 검색 할 수 없습니까? 결국 LSTCities가 데이터 소스에서 데이터를 검색하는 순간, lstcities.selectedValue는 값이 설정되어 있습니까?



고맙습니다


두 번째 편집 :

더 빨리 답장하지 않은 것에 대해 사과 드리지만, 당신이 대답했다는 것을 몰랐습니다. 그리고 내가했을 때, 나는 3 개의 브레인 셀이 제대로 작동하도록하려고 20 분을 보냈지 만, 내가 성공했는지 확실하지 않습니다.


a) 따라서 ControlParameter는 C.C1을 평가하므로 C가 결속 된 후 C.C1의 값을 검색합니다!


Q1- ControlParameter는 자체 상태 만 읽고 변경되었는지 확인하기 위해서만 읽습니다.

a) 컨트롤 파라미터는 바인딩이 발생하기 전에 뷰 스테이트가 변경되었는지 확인합니다 (onparameterChanged 이벤트를 시작) -> 따라서 page.onloadcomplete 동안 viewstate를 확인합니다. 그러나 ControlParameter는 ViewState가 변경되었다는 것을 어떻게 알 수 있습니까 (첫 번째 Postback에서 알 수 있습니까)? 결국, 처음부터 페이지가 생성 될 때부터 ControlParameter의 ViewState는 항상 더러운 것으로 표시되므로, 한 포스트 백에서 다른 백에서 다른 백에서 다른 값이 Postbacks 사이에서 값이 변경되었는지 여부를 어떻게 알 수 있습니까?

b) ControlParameter는 viewstate가 OnParameterChanged 이벤트를 발사 할 수 있도록 만 변경 여부를 확인한다고 가정합니다. 그러나 왜 그 사건을 처리하는 것이 그렇게 중요한가?


부동산 평가가 처음으로 페이지에있는 것은 페이지에 있습니다.

속성 평가에 의해 당신은 자체 뷰 스테이트를 확인하는 ControlParameter를 의미합니까? 따라서 C.C1을 평가하는 ControlParameter를 의미하지는 않습니다 (C가 결속 된 후 발생한다고 가정합니다).


당신의 도움에 정말 감사합니다


세 번째 편집 :

다시 시간을내어 죄송합니다. 마지막 편집을하기 위해 최선을 다할 것입니다.


Update ()는 OnloadComplete 및 데이터 바인딩이 발생할 때 모두 호출됩니다. 내부 업데이트 () 다음 문장도 실행됩니다.

this.ViewState["ParameterValue"] = actualValue;

따라서 데이터 바인딩이 발생할 때 update ()가 호출되는 경우 다음 Postback Update ()가 OnloadComplete에서 호출되면 C.C1과 ControlParameter가 이미 동일한 값을 가지게됩니다.

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

OnloadComplete에서 Update ()가 호출 될 때 항상 False를 반환합니다. 따라서 OnParameterChanged 이벤트가 발사되지 않습니까? 1 그렇다면 OnloadComplete에서 Update () 호출 할 필요가 없습니다!


감사합니다

도움이 되었습니까?

해결책

첫 번째 가정이 맞습니다.

두 번째 질문에, 그것은 그것이 포스트 백인지 아닌지 및/또는 명시 적으로 구속력이 있는지 여부에 따라 다릅니다. 포스트 백이 아니고 바인딩이 자동으로 발생하는 경우 대략적으로 말하면, DataSourceView가 OnSelecting 이벤트 직전에 DataBind에서 SELECT를 호출 할 때 ControlParameter의 값이 검색됩니다. 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

따라서 제어 계층 구조의 각 컨트롤에 대해 프레임 워크는 데이터를 재귀 적으로 호출하여 매개 변수의 검색, OnSelecting, 데이터 검색 및 OnSelected를 트리거합니다.

그러나 포스트 백인 경우 해당 매개 변수는 페이지의 onloadcomplete의 ViewState에서 선언 된 순서대로로드됩니다.

이것이 당신이 찾고 있던 것입니까?

편집하다

Q1- ControlParameter가 Control C의 속성 C1에 결합되어 있다고 가정합시다 ?!

그것은 전적으로 그것이 어떻게 일어나는지가 아닙니다 ... 포스트 백 (그리고 그 문제에 대한 초기 요청)에서 ControlParemeter의보기 상태는 onparameterChanged 이벤트가 발사 될 수 있도록 변경되었는지 확인하기 위해 평가됩니다. ControlParameter의 실제 값은 (반사를 통해) IT가 가리키는 대조군에 대해 평가됩니다. 귀하의 경우 "C.C1"입니다. 이제 C.C1을 읽을 때 값은보기 상태에서 읽을 가능성이 높습니다. 그러나 ControlParameter는 C의보기 상태를 직접 읽지 않습니다.

Q2- 그러나 왜 페이지가 처음으로 작성되었는지 묻는 이유를 물어볼 수 있습니까? ControlParameter의 값도 ViewState에서 검색 할 수 없습니까? 결국 LSTCities가 데이터 소스에서 데이터를 검색하는 순간, lstcities.selectedValue는 값이 설정되어 있습니까?

그 시점에서 LSTCities는 아직 데이터를 검색하지 않았습니다. 부동산 평가가 처음으로 Page.OnloadComplete에 있지만 DataBind (Page.PrerenderRecursiveInal이 발사 될 때 곧 발생).

조잡한 형태로 페이지의 수명 주기로 배치하려고합니다.

...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가 결속 된 후 C.C1의 값을 검색합니다!

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

a) 그래서 ControlParameter는 ViewState가 변경되었는지 확인합니다 ...

ViewState를 사용하는 방법을 보려면 위의 UpdateValue 메소드를 참조하십시오.

b) ControlParameter는 viewstate가 OnParameterChanged 이벤트를 발사 할 수 있도록 만 변경 여부를 확인한다고 가정합니다. 그러나 왜 그 사건을 처리하는 것이 그렇게 중요한가?

나는 그것이 중요하다는 것을 모른다. 다른 이벤트와 마찬가지로 파라미터 속성의 변경 사항을 추적하고 귀하의 요구에 따라 행동 할 수 있다고 생각합니다. 여러 곳에서 해고되지만 누군가가 구독 한 위치를 보지 못합니다. 그래서...

속성 평가에 의해 당신은 자체 뷰 스테이트를 확인하는 ControlParameter를 의미합니까? 따라서 C.C1을 평가하는 ControlParameter를 의미하지는 않습니다 (C가 결속 된 후 발생한다고 가정합니다).

이는 명시된 이유로 ViewState를 확인한 다음 ControlParameter.upDateValue가 호출 된 다음 ControlParameter.evalue를 호출 한 다음 컨트롤을 찾아 반사 (Eval)를 사용하여 데이터를 검색 함을 의미합니다. 위 참조.

세 번째 편집

업데이트로 업데이트 value를 의미한다고 가정합니다.

따라서 데이터 바인딩이 발생할 때 Update ()가 호출되면 다음 Postback Update ()가 OnloadComplete에서 호출되면 C.C1 및 ControlParameter가 이미 동일한 값을 가지고 있다는 의미입니다.

필요하지 않습니다. view 상태가 LoadAllState에로드되었고 OnloadComplete 사이에 6 단계가 더 있습니다 (위의 페이지 수명주기 참조). 이들 각각은 소스 컨트롤 (C.C1) 값을 수정할 수 있습니다.

c.c1 = "x"가 있고 뒤로 포스트를했다고 가정 해 봅시다. 이제 모든 컨트롤의 뷰 상태가로드됩니다 (loadAllState). C.C1이 뷰 상태에 값을 저장하면 "x"를로드합니다. page_load (loadRecursive)에서 c.c1 = "y"를 설정하기로 결정합니다. 여기에서 c.c1은 "y"를 뷰 상태에 보관하기로 결정할 수 있습니다. 그런 다음 다른 이벤트가 따릅니다. 다음은 OnloadComplete가 온다. SQLDATASOURCE는이 이벤트에 가입하므로 모든 관련 매개 변수 (LoadCompleTeeventhandler)를 평가할 것이며 C.C1을 변경했지만 ControlParameter의 뷰 상태는 그렇지 않았습니다.

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

진정으로 돌아 오면 onparameterChanged가 해고됩니다. 그건 그렇고,이 이벤트가 트리거되는 다른 장소가 10 개 이상 있습니다. 데이터 바인딩 및 속성 검색 프로세스에서 큰 역할을 수행하지 않습니다 (있는 경우).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top