تهيئة التحكم في الطفل في مركب مخصص في ASP.NET
-
02-07-2019 - |
سؤال
من الواضح أن جزءًا من سلسلة عناصر التحكم التي أعمل عليها يتضمن تجميع بعضها معًا في مركبات.لقد بدأت أتعلم بسرعة أن هذا الأمر يأخذ في الاعتبار (كل هذا جديد بالنسبة لي!) :)
لدي في الأساس StyledWindow
السيطرة، والتي هي في الأساس تمجيد Panel
مع القدرة على القيام بأجزاء أخرى (مثل إضافة حدود وما إلى ذلك).
هذا هو الكود الذي يقوم بإنشاء مثيل لعناصر التحكم التابعة بداخله.حتى هذه اللحظة يبدو أنه كان يعمل بشكل صحيح مع عناصر التحكم الثابتة الدنيوية:
protected override void CreateChildControls()
{
_panel = new Panel();
if (_editable != null)
_editable.InstantiateIn(_panel);
_regions = new List<IAttributeAccessor>();
_regions.Add(_panel);
}
ظهرت المشاكل اليوم عندما حاولت دمج عنصر تحكم أكثر تعقيدًا بداخله.يستخدم عنصر التحكم هذا مرجعًا للصفحة نظرًا لأنه يقوم بإدخال JavaScript لجعلها أكثر سرعة واستجابة قليلاً ( RegisterClientScriptBlock
هو السبب الوحيد الذي يجعلني أحتاج إلى مرجع الصفحة).
الآن، كان هذا يسبب أخطاء "كائن فارغ"، لكنني قمت بترجمة هذا إلى طريقة العرض، والتي كانت بالطبع تحاول استدعاء الطريقة مقابل [خالية] Page
هدف.
ما يحيرني هو أن عنصر التحكم يعمل بشكل جيد كوحدة مستقلة، ولكن عند وضعه في StyledWindow
كل شيء يسير على نحو خاطئ فظيعة!
لذا، يبدو أنني أفتقد شيئًا ما في أي منهما StyledWindow
أو ChildControl
.أيه أفكار؟
تحديث
مثل براد ويلسون تمت الإشارة إليه بحق، فأنت لا ترى أن عناصر التحكم تتم إضافتها إلى ملف Controls
مجموعة.هذا ما _panel
كان هذا موجودًا للتعامل مع ذلك بالنسبة لي، ثم تجاوزه بشكل أساسي Controls
(حصلت على هذا من دليل في مكان ما):
Panel _panel; // Sub-Control to store the "Content".
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return _panel.Controls;
}
}
آمل أن يساعد ذلك في توضيح الأمور.اعتذارات.
تحديث المتابعة إجابة Longhorn213
حسنًا، لقد كنت أقوم ببعض التلاعب بعناصر التحكم، حيث قمت بوضع واحدة داخل المركب وواحدة بالخارج.حصلت بعد ذلك على حالة الصفحة في الحدث الرئيسي في دورة حياة عنصر التحكم وقمت بتقديمها إلى الصفحة.
المستقل يعمل بشكل جيد ويتم تهيئة الصفحة كما هو متوقع.ومع ذلك، فإن المتداخلة في المركب مختلفة.إنه OnLoad
لا يتم إطلاق الحدث على الإطلاق!لذلك أعتقد أن براد ربما يكون على حق في أنني لا أقوم بإعداد التسلسل الهرمي للتحكم بشكل صحيح، هل يمكن لأي شخص تقديم بعض النصائح بشأن ما أفتقده؟هل طريقة اللوحة غير كافية؟(حسنًا، من الواضح أنه ليس كذلك؟!) :D
شكرا لمساعدتكم يا رفاق، موضع تقدير :)
المحلول 3
تم حلها!
حسنًا، لقد كنت مصممًا على حل هذا الأمر اليوم!وهنا كانت أفكاري:
- اعتقدت استخدام
Panel
كان بمثابة اختراق إلى حد ما، لذا يجب أن أقوم بإزالته ومعرفة كيف يتم ذلك بالفعل. - لم أكن أريد أن أفعل شيئًا مثل
MyCtl.Controls[0].Controls
للوصول إلى عناصر التحكم المضافة إلى المركب. - أردت أن يعمل الشيء اللعين!
لذا، قمت بالبحث وضربت MSDN, هذه المادة كان حقًا مفيد (أيمثل النسخ واللصق تقريبًا، ويتم شرحه جيدًا - وهو أمر سيئ في MSDN تقليديًا).لطيف - جيد!
لذلك، قمت بإلغاء استخدام Panel
واتبعت المقالة إلى حد كبير واعتبرتها إنجيلًا، وسجلت الملاحظات أثناء ذهابي.
إليك ما لدي الآن:
- تعلمت أنني كنت أستخدم المصطلح الخطأ.كان يجب أن أسميها أ التحكم القالبي.في حين أن عناصر التحكم المقولبة هي مركبات من الناحية الفنية، إلا أن هناك فرقًا واضحًا.يمكن لعناصر التحكم المُقالبة تحديد الواجهة للعناصر التي تتم إضافتها إليها.
- تعتبر عناصر التحكم النموذجية قوية جدًا وسريعة جدًا وسهلة الإعداد بمجرد أن تضع رأسك عليها!
- سوف ألعب المزيد مع دعم المصمم للتأكد من أنني أفهم كل شيء بشكل كامل، ثم أقوم بنشر مدونة :)
- يتم استخدام عنصر التحكم "القالب" لتحديد الواجهة للبيانات النموذجية.
على سبيل المثال، إليك علامة ASPX لعنصر التحكم المقولب:
<cc1:TemplatedControl ID="MyCtl" runat="server">
<Template>
<!-- Templated Content Goes Here -->
</Template>
</cc1:TemplatedControl>
إليك الكود الموجود لدي الآن
public class DummyWebControl : WebControl
{
// Acts as the surrogate for the templated controls.
// This is essentially the "interface" for the templated data.
}
في TemplateControl.cs...
ITemplate _template;
// Surrogate to hold the controls instantiated from
// within the template.
DummyWebControl _owner;
protected override void CreateChildControls()
{
// Note we are calling base.Controls here
// (you will see why in a min).
base.Controls.Clear();
_owner = new DummyWebControl();
// Load the Template Content
ITemplate template = _template;
if (template == null)
template = new StyledWindowDefaultTemplate();
template.InstantiateIn(_owner);
base.Controls.Add(_owner);
ChildControlsCreated = true;
}
ثم، لتوفير سهولة الوصول إلى عناصر التحكم في الكائن [البديل]:
(ولهذا السبب احتجنا إلى مسح/إضافة عناصر التحكم الأساسية)
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return _owner.Controls;
}
}
وهذا إلى حد كبير، سهل عندما تعرف كيف!:)
التالي: دعم منطقة وقت التصميم!
نصائح أخرى
لا أرى أنك تضيف عناصر التحكم الخاصة بك إلى مجموعة عناصر التحكم في أي مكان، وهو ما يفسر سبب عدم تمكنهم من الوصول إلى الصفحة (نظرًا لأنه لم يتم وضعها رسميًا على الصفحة مطلقًا).
لقد قمت دائمًا بإجراء مكالمات JavaScript على وظيفة OnLoad.مثل أدناه.
protected override void OnLoad(EventArgs e)
{
// Do something to get the script
string script = GetScript();
this.Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "SomeJavaScriptName", script);
// Could also use this function to determine if the script has been register. i.e. more than 1 of the controls exists
this.Page.ClientScript.IsClientScriptBlockRegistered("SomeJavaScriptName");
base.OnLoad(e);
}
إذا كنت لا تزال ترغب في إجراء العرض، فيمكنك فقط كتابة البرنامج النصي في الرد.وهذا ما يفعله RegisterScriptBlock، فهو يقوم فقط بوضع البرنامج النصي في الصفحة.
حسنًا، لقد بدأت اللعب واكتشفت أن هناك خطأ ما في إنشاء مثيل التحكم الخاص بي، نظرًا لأن Longhorn كان على حق، فيجب أن أكون قادرًا على إنشاء مراجع البرامج النصية في OnLoad
(وأنا لم أستطع)، وكان براد على حق في أنني بحاجة للتأكد من حقوقي Controls
تم الحفاظ على التسلسل الهرمي عن طريق الإضافة إلى Controls
جمع المركب.
لذلك كان عندي شيئين هنا:
- لقد تجاوزت
Controls
خاصية الوصول للمركب لإرجاع هذاPanel
مجموعة عناصر التحكم لأنني لا أريد أن أذهبctl.Controls[0].Controls[0]
للوصول إلى السيطرة الفعلية التي أريدها. لقد قمت بإزالة هذا، لكني بحاجة إلى حل هذا الأمر. - لم أكن قد أضفت
Panel
إلىControls
مجموعة، لقد فعلت هذا الآن.
لذلك، فإنه يعمل الآن، ولكن كيف يمكنني الحصول على Controls
خاصية للمركب لإرجاع العناصر الموجودة في Panel
, ، بدلا من Panel
بحد ذاتها؟