إذا تم دائما ربط عناصر التحكم في عناصر تحكم مصدر البيانات بالترتيب الذي تم إعلانه بعد ذلك

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

سؤال


أ) تستند السؤال أدناه إلى افتراض أن الضوابط مرتبطة دائما عناصر تحكم مصدر البيانات بالترتيب الذي أعلن عنه؟ لذلك في مثالنا SQLDASource1 سيتصل بمصدر البيانات قبل SQLDASource2 وبالتالي LSCISITS. سيتم ملؤها بالقيم من قبل gridview1., والسبب في ذلك LSCISITS. أعلن من قبل gridview1.?!



ب) إذا كان الأمر كذلك، فما عند بالضبط controlparameter. استرداد قيمة من قائمة منسدلةب أفترض أنه بعد sqldatasource1_stlate () معالج الأحداث وقبل 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>


ثناكس

تعديل:

ومع ذلك، إذا كان ذلك عاجلا، فسيتم تحميل هذه المعلمات من ViewState في Onloadcomplete الصفحة، مرة أخرى، بالترتيب الذي يتم الإعلان عنه.

Q1 - دعونا نفترض التحكم بالتحكم بالملكية الخاصة بممتلكات C1 من عنصر تحكم C. وأود أن أتصور أنه على أبعد من ذلك، سيكون ControlProperty دائما من الحصول على قيمة C.C1 من ViewState، بغض النظر عن نوع C هو، وحتى إذا كان C عرض ViewState من جديد

Q2 - ولكن هل لي أن أسأل لماذا، إذا تم إنشاء صفحة لأول مرة، فلا يمكن استرداد قيمة VisiterParameter من ViewState؟ بعد ذلك، تسترجع LSCISITYS لحظة البيانات من مصدر البيانات، LSCites.Secites.SelectedValue لديه مجموعة قيمتها؟



ثناكس ميت


تحرير الثاني:

أعتذر عن عدم الرد عاجلا، لكنني لم أكن أدرك أنك أجابت. وعندما فعلت، قضيت جيدة 20 دقيقة في محاولة للحصول على 3 لدغاكيلز بلدي للعمل بشكل صحيح، لكنني لست متأكدا مما إذا نجحت تماما


A) So ControlParameter يقيم C.C1 وبالتالي يسترجع قيمة C.C1 بعد أن تم ربط C؟!


Q1 - ControlParameter يقرأ فقط حالته الخاصة فقط لتحديد ما إذا كان قد تغير

أ) يتحقق ControlParameter ما إذا كانت العطلات العظيمة التي تم تغييرها (من أجل إطلاق الحدث OnParameterertchanged) قبل إجراء التوصيل -> هكذا، فهذا فهو يتحقق من ViewState خلال الصفحة. ولكن كيف سيعلم التحكم VightParameter أن عرض المشاهد قد تغير (سيعرف أولا عن عونك)؟ بعد ذلك، من المرة الأولى التي يتم فيها إنشاء الصفحة التي يتم فيها إنشاء ViewState ControlParameter ستحصل دائما على أنها قذرة، فكيف، من إنشاء واحد إلى آخر، يعرف ControlParameter ما إذا كانت قيمتها قد تغيرت بين أبعاد البريد؟

ب) افترض أن ControlParameter يتحقق مما إذا غير عرض المشاهد إلا حتى تتمكن من إطلاق الحدث onparametererterged. ولكن لماذا يتعامل مع هذا الحدث مهم جدا؟


في المرة الأولى التي يحدث فيها تقييم العقار يحدث في الصفحة.

عن طريق تقييم العقار تقصد ControlParameter التحقق من العارض الخاصة به؟ وبالتالي، لا تقصد ControlParameter تقييم C.C1 (الذي حدث يحدث بعد C بعد


انا فعلا اقدر مساعدتك


تحرير الثالث:

أنا آسف حقا لأخذ وقتك مرة أخرى، سأبذل قصارى جهدي لجعل هذا التحرير الأخير.


يتم استدعاء تحديث () في Onloadcomplete وعندما يحدث ملزمة البيانات. في الداخل تحديث () يتم تنفيذ الجملة التالية أيضا:

this.ViewState["ParameterValue"] = actualValue;

لذلك إذا تم استدعاء التحديث () عند إجراء ملزمة البيانات، فما يعني ذلك هذا هو أنه عند بدء تشغيل Onloadcomplete () في Onloadcomplete، سيكون C.C1 و ControlParameter بالفعل نفس القيم وبالتالي

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

سيعود دائما FALSE (عند التحديث () يتم استدعاؤه في Onloadcomplete)، وبالتالي لن يتم إطلاق الحدث OnParametereretererterged أبدا؟ 1 إذا كان الأمر كذلك، فافشل في رؤية الحاجة إلى الاتصال بالتحديث () في 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

لذلك، لكل عنصر تحكم في التسلسل الهرمي للتحكم، يستدعي الإطار بشكل متكرر بيانات التعطل، والذي يقوم بعد ذلك بمشغلات استرجاع المعلمات، ويتم تحديدها، واسترجاع البيانات، وحفظها.

ومع ذلك، إذا كان ذلك عاجلا، فسيتم تحميل هذه المعلمات من ViewState في Onloadcomplete الصفحة، مرة أخرى، بالترتيب الذي يتم الإعلان عنه.

هل هذا هو ما كنت تبحث عنه؟

يحرر

Q1 - دعونا نفترض التحكم بالتحكم بالملكية الخاصة بممتلكات C1 من عنصر تحكم C. وأود أن أتصور أنه على أبعد من ذلك، سيكون ControlProperty دائما من الحصول على قيمة C.C1 من ViewState، بغض النظر عن نوع C هو، وحتى إذا كان C عرض ViewState من جديد

هذا ليس تماما كيف يحدث ذلك ... عند النشر مرة أخرى (وعلى الطلب الأولي لهذه المسألة)، يتم تقييم حالة عرض ControlPareremeter فقط لمعرفة ما إذا كان قد تغير حتى يتم إطلاق الحدث OnParameterChanged. يتم تقييم القيمة الفعلية ل ControlParameter مقابل عنصر التحكم الذي يشير إليه (عبر الانعكاس). في حالتك، سيكون "c.c1". الآن، عندما يقرأ C.C1، من المرجح أن تقرأ قيمتها من حالة عرض. ولكن في أي وقت، يقوم ControlParameter بقراءة حالة عرض C. مباشرة.

Q2 - ولكن هل لي أن أسأل لماذا، إذا تم إنشاء صفحة لأول مرة، فلا يمكن استرداد قيمة VisiterParameter من ViewState؟ بعد ذلك، تسترجع LSCISITYS لحظة البيانات من مصدر البيانات، LSCites.Secites.SelectedValue لديه مجموعة قيمتها؟

هذا هو الشيء، في تلك المرحلة (الأحمال المرة الأولى)، لم يتم استرداد LSCISITS أي بيانات حتى الآن. في المرة الأولى التي يحدث فيها تقييم الممتلكات في الصفحة .Onloadcomplete، ولكن قبل أي قاعدة بيانات (يحدث بعد فترة وجيزة، عند إطلاق الصفحة. يتم إطلاق الصفحة.

في شكل الخام، في محاولة لوضعه في دورة حياة من الصفحة:

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

التحرير الثاني

لذلك يقوم ConstrumentParameter بتقييم C.C1 وبالتالي يسترجع قيمة C.C1 بعد C قد تم ربطه؟!

يسترجع ControlParameter القيم كلما طلب ذلك، وهو ما يحدث في هذا السيناريو (بشكل غير مباشر) في مكانين: Onloadcomplete و DataBind (الناتج عن ProrenderReCursiveInternal). على Onloadcomplete، ليس C غير مرتبط. على prerenderrecursiveInternal، بعد بيانات التعطل، يجب أن تكون 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 يتحقق مما إذا غير عرض المشاهد إلا حتى تتمكن من إطلاق الحدث onparametererterged. ولكن لماذا يتعامل مع هذا الحدث مهم جدا؟

أنا لا أعرف أنه من المهم. أفترض، مثل أي حدث آخر، يسمح لك بتتبع التغييرات في خصائص المعلمة وتتصرف وفقا لاحتياجاتك. يتم إطلاقه في العديد من الأماكن، لكنني لا أرى أين يبلغ ذلك. وبالتالي...

عن طريق تقييم العقار تقصد ControlParameter التحقق من العارض الخاصة به؟ وبالتالي، لا تقصد ControlParameter تقييم C.C1 (الذي حدث يحدث بعد C بعد

وهذا يعني أنه يطلق عليه اسم ControlParmeter.updateValue، الذي يتحقق من ViewState لأسباب محددة، ثم يستدعي ControlParameter.Evalue، والذي يقع بعد ذلك، ثم يعثر على عنصر تحكم واسترداد البيانات باستخدام التفكير (EVER). أنظر فوق.

تحرير الثالث

أفترض أنه من خلال تحديث تقصد UpdateValue.

لذلك إذا تم استدعاء التحديث () عند إجراء ملزم البيانات، فما يعني ذلك هذا هو أنه عند تشغيل تحديث Postback التالي () في Onloadcomplete، C.C1 و ControlParameter سيكون له بالفعل نفس القيم ...

ليس من الضروري. أنت تنسى أن يتم تحميل حالة العرض على LoadallState وبينه وبين onloadcomplete هناك ست خطوات إضافية (انظر الصفحة دورة الحياة أعلاه). قد يقوم كل من هؤلاء بتعديل قيمة التحكم بالمصدر (C.C1).

قل لديك c.c1 = "x" وفعلت بعد الظهر. الآن، يتم تحميل حالة العرض لجميع عناصر التحكم (loadallstate). إذا تم تخزين C.C1 القيمة في حالة العرض، فستحميل "X". في page_load (loadReCursive) تقرر تعيين c.c1 = "y". قد تقرر هنا C.C1 تخزين "y" في ولاية رأيها أم لا - إنه غير ذي صلة. ثم الأحداث الأخرى تتبع. التالي يأتي Onloadcomplete. نظرا لأن SQLDATASource تضبط في هذا الحدث، فستقيم جميع المعلمات المرتبطة (LOADCOMPOMPLETEEVENTERLER) و، لأنك قمت بتغيير C.C1، لكن حالة عرض ControlParameter لم يفعل ذلك

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

سوف يعود صحيحا وينبغي إطلاق النار. بالمناسبة، هناك ما لا يقل عن عشر أماكن أخرى حيث يتم تشغيل هذا الحدث. لا يلعب دورا كبيرا (إن وجد) في عملية تجليد البيانات واسترجاع الممتلكات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top