سؤال

أحاول الالتفاف حول asp.net.لدي خبرة طويلة كمطور PHP، ولكنني أواجه الآن مهمة تعلم asp.net وأواجه بعض المشاكل في ذلك.قد يكون السبب في ذلك هو أنني أحاول فرض إطار العمل على شيء غير مخصص له - لذا أود أن أتعلم كيفية القيام بذلك "بالطريقة الصحيحة".:-)

مشكلتي هي كيفية إضافة عناصر تحكم إلى الصفحة برمجياً في وقت التشغيل.بقدر ما أستطيع معرفة أنك بحاجة إلى إنشاء عناصر التحكم في page_init لأنها تختفي في PostBack التالي.لكن في كثير من الأحيان أواجه مشكلة أنني لا أعرف عناصر التحكم التي يجب إضافتها في page_init لأنها تعتمد على قيم من PostBack السابقة.

يمكن أن يكون السيناريو البسيط نموذجًا مزودًا بعنصر تحكم منسدل مضاف في المصمم.تم تعيين القائمة المنسدلة على AutoPostBack.عند حدوث PostBack، أحتاج إلى عرض عنصر تحكم واحد أو أكثر اعتمادًا على القيمة المحددة من عنصر تحكم القائمة المنسدلة ويفضل أن تعمل عناصر التحكم هذه كما لو كانت قد تمت إضافتها بواسطة التصميم (كما في "عند إعادة النشر، تتصرف "بشكل صحيح").

هل أسير في الطريق الخطأ هنا؟

هل كانت مفيدة؟

المحلول

وأنا أتفق مع النقاط الأخرى الواردة هنا "إذا كان بإمكانك الخروج من إنشاء عناصر التحكم ديناميكيًا، فافعل ذلك..." (بواسطة @جيسبر بلاد جنسون الملقب) ولكن إليك خدعة عملت عليها باستخدام عناصر التحكم التي تم إنشاؤها ديناميكيًا في الماضي.

المشكلة تصبح الدجاجة والبيضة.أنت بحاجة إلى ViewState الخاص بك لإنشاء شجرة التحكم وتحتاج إلى إنشاء شجرة التحكم الخاصة بك للوصول إلى ViewState الخاص بك.حسنا، هذا صحيح تقريبا.هناك طريقة للحصول على قيم ViewState الخاصة بك فقط قبل بقية الشجرة مأهولة بالسكان.وذلك بالتجاوز LoadViewState(...) و SaveViewState(...).

في SaveViewState قم بتخزين عنصر التحكم الذي ترغب في إنشائه:

protected override object SaveViewState()
{
    object[] myState = new object[2];
    myState[0] = base.SaveViewState();
    myState[1] = controlPickerDropDown.SelectedValue;

    return myState
}

عندما يستدعي إطار العمل تجاوز "LoadViewState" الخاص بك، فسوف تستعيد الكائن الدقيق الذي قمت بإرجاعه من "SaveViewState":

protected override void LoadViewState(object savedState) 
{
    object[] myState = (object[])savedState;

    // Here is the trick, use the value you saved here to create your control tree.
    CreateControlBasedOnDropDownValue(myState[1]);

    // Call the base method to ensure everything works correctly.
    base.LoadViewState(myState[0]);
}

لقد استخدمت هذا بنجاح لإنشاء صفحات ASP.Net حيث تم تسلسل DataSet إلى ViewState لتخزين التغييرات على شبكة كاملة من البيانات مما يسمح للمستخدم بإجراء تعديلات متعددة باستخدام PostBacks وأخيرًا الالتزام بجميع تغييراتهم في "حفظ" واحد. عملية.

نصائح أخرى

يجب عليك إضافة عنصر التحكم الخاص بك داخل حدث OnInit وسيتم الحفاظ على حالة العرض.لا تستخدم if(ispostback)، لأنه يجب إضافة عناصر التحكم في كل مرة، في كل مرة يحدث فيها إعادة النشر!
(De) يحدث تسلسل حالة العرض بعد OnInit وقبل OnLoad، لذلك سيرى موفر ثبات حالة العرض الخاص بك عناصر التحكم المضافة ديناميكيًا إذا تمت إضافتها في OnInit.

ولكن في السيناريو الذي تصفه، ربما يكون العرض المتعدد أو الإخفاء/الإظهار البسيط (خاصية مرئية) هو الحل الأفضل.
هذا لأنه في حدث OnInit، عندما يتعين عليك قراءة القائمة المنسدلة وإضافة عناصر تحكم جديدة، لم تتم قراءة حالة العرض (إلغاء تسلسلها) حتى الآن ولا تعرف ماذا اختار المستخدم!(يمكنك القيام بـ request.form()، لكن هذا يبدو خاطئًا نوعًا ما)

بعد أن تصارعت مع هذه المشكلة لبعض الوقت، توصلت إلى هذه القواعد الأساسية التي يبدو أنها ناجحة، ولكن YMMV.

  • استخدم عناصر التحكم التصريحية كلما أمكن ذلك
  • استخدم ربط البيانات حيثما أمكن ذلك
  • فهم كيفية عمل ViewState
  • يمكن لخاصية Visibilty أن تقطع شوطا طويلا
  • إذا كان يجب عليك استخدام عناصر التحكم الإضافية في معالج الأحداث، فاستخدم نصيحة Aydsman وأعد إنشاء عناصر التحكم في LoadViewState الذي تم تجاوزه.

فهم حقًا لحالة العرض يجب قراءته.

فهم عناصر التحكم الديناميكية بالقدوة يعرض بعض التقنيات حول كيفية استخدام ربط البيانات بدلاً من عناصر التحكم الديناميكية.

فهم حقيقي لعناصر التحكم الديناميكية يوضح أيضًا التقنيات التي يمكن استخدامها لتجنب الضوابط الديناميكية.

نأمل أن يساعد هذا الآخرين الذين يعانون من نفس المشاكل.

إذا كنت تريد حقًا استخدام عناصر التحكم الديناميكية، فيجب أن يعمل ما يلي:

  • في OnInit، قم بإعادة إنشاء نفس التسلسل الهرمي للتحكم الذي كان موجودًا على الصفحة عند تلبية الطلب السابق.(إذا لم يكن هذا هو الطلب الأولي بالطبع)
  • بعد OnInit، سيقوم إطار العمل بتحميل حالة العرض من الطلب السابق ويجب أن تكون جميع عناصر التحكم الخاصة بك في حالة مستقرة الآن.
  • في OnLoad، قم بإزالة عناصر التحكم غير المطلوبة وأضف العناصر الضرورية.سيكون عليك أيضًا حفظ شجرة التحكم الحالية بطريقة ما في هذه المرحلة، لاستخدامها في الخطوة الأولى أثناء الطلب التالي.يمكنك استخدام متغير جلسة العمل الذي يحدد كيفية إنشاء شجرة التحكم الديناميكية.حتى أنني قمت بتخزين مجموعة عناصر التحكم بالكامل في الجلسة مرة واحدة (ضع مذراتك جانبًا، لقد كان ذلك للعرض فقط).

تبدو إعادة إضافة عناصر التحكم "القديمة" التي لن تحتاج إليها وستتم إزالتها عند OnLoad أمرًا غريبًا بعض الشيء، ولكن Asp.Net لم يتم تصميمه حقًا مع وضع إنشاء التحكم الديناميكي في الاعتبار.إذا لم يتم الحفاظ على نفس التسلسل الهرمي للتحكم أثناء تحميل حالة العرض، فستبدأ جميع أنواع الأخطاء التي يصعب العثور عليها كامنة في الصفحة، لأنه يتم تحميل حالات عناصر التحكم القديمة إلى عناصر التحكم المضافة حديثًا.

اقرأ دورة حياة صفحة Asp.Net وخاصةً كيفية عمل حالة العرض وستصبح واضحة.

يحرر:هذه مقالة جيدة جدًا حول كيفية تصرف حالة العرض وما يجب عليك مراعاته أثناء التعامل مع عناصر التحكم الديناميكية: http://geekswithblogs.net/FrostRed/archive/2007/02/17/106547.aspx

حسنًا.إذا كان بإمكانك الخروج من إنشاء عناصر التحكم ديناميكيًا، فافعل ذلك - وإلا، فما يجب أن أفعله هو استخدام Page_Load بدلاً من Page_Init، ولكن بدلاً من وضع الأشياء داخل If Not IsPostBack، قم بتعيين i مباشرة في الطريقة.

آه، هذه هي مشكلة التجريد المتسرب لنماذج الويب ASP.NET.

ربما ستكون مهتمًا بإلقاء نظرة على ASP.NET MVC، والذي تم استخدامه لإنشاء موقع ويب stackoverflow.com هذا؟من المفترض أن يكون ذلك مناسبًا لك بشكل أسهل، لأنه يأتي من خلفية PHP (وبالتالي، عندما يتعلق الأمر بـ HTML وJavascript).

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

ربما يمكنك حتى ربط بيانات خاصية العرض الحالية لطريقة العرض المتعددة بقيمة القائمة المنسدلة!

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

لقد واجهت هذا في كتاب "Pro ASP.NET 3.5 في C# 2008" ضمن قسم إنشاء التحكم الديناميكي:

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

لم أختبر هذا، ولكن قد تنظر في الأمر.

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