كيف يمكنني الاستيلاء على الأحداث من دون ضوابط على المستخدم التحكم في WinForms التطبيق ؟
-
03-07-2019 - |
سؤال
هل هناك أي طريقة للحصول على النموذج الرئيسي لتكون قادرة على اعتراض أحداث إطلاق النار على subcontrol على المستخدم التحكم ؟
لدي مخصص للمستخدم التحكم المضمنة في النموذج الرئيسي من التطبيق.التحكم يحتوي على مختلف subcontrols أن التعامل مع البيانات نفسها التي يتم عرضها من قبل عناصر التحكم الأخرى في النموذج الرئيسي.ما أود هو إذا كان الشكل الرئيسي يمكن أن يكون على علم بطريقة أو بأخرى عندما يقوم المستخدم بتغيير subcontrols ، حتى أتمكن من تحديث البيانات و المقابلة العرض في أماكن أخرى.
الآن, أنا الغش.لدي مندوب التوصيل إلى التركيز ترك الحدث من subcontrols.هذا مندوب التغييرات العقار المستخدم-التحكم أنا لا تستخدم في مكان آخر (في هذه القضية ، CausesValidation).ثم يكون مندوبا المحددة في النموذج الرئيسي عند CausesValidation ملك للمستخدم التحكم في التغييرات التي توجه التطبيق لتحديث البيانات وعرضها.
تنشأ مشكلة لأنني أيضا مندوب اقامة عندما التركيز يترك المستخدم-التحكم لأنني بحاجة إلى التحقق من صحة الحقول في المستخدم-التحكم قبل أن تسمح للمستخدم أن تفعل أي شيء آخر.ومع ذلك ، إذا كان المستخدم هو فقط التبديل بين subcontrols لا ترغب في التحقق من صحة, لأنها قد لا يتم التحرير.
ويوفر البيانات لتحديث عندما ينتقل المستخدم subcontrols أو يترك للمستخدم التحكم ، ولكن ليس من صحة.عندما يترك المستخدم التحكم أريد أن التحديث والتحقق من صحة.الآن ترك المستخدم-التحكم أسباب المصادقة على النار مرتين.
المحلول
أفضل الممارسات تعرض الأحداث على UserControl
أن فقاعة الأحداث تصل إلى النموذج الأصلي.لقد ذهبت قبل وضعت معا مثال لك.هنا هو وصف ما يقدم هذا المثال.
UserControl1
- إنشاء
UserControl
معTextBox1
- تسجيل الحدث العام على
UserControl
دعاControlChanged
- داخل
UserControl
تسجيل الحدث معالجTextBox1
TextChangedEvent - داخل
TextChangeEvent
معالج وظيفة أسميهControlChanged
الحدث فقاعة إلى النموذج الأصلي
- إنشاء
Form1
- قطرة مثيل
UserControl1
على المصمم - تسجيل معالج الحدث على
UserControl1
بالنسبةMouseLeave
وControlChanged
- قطرة مثيل
هنا هو لقطة توضح أن ControlChanged
حدث أنني محددة على UserControl
متاح من خلال UX في Visual Studio على الوالدين نموذج Windows.
نصائح أخرى
وأفضل نموذج لهذا النوع من الاشياء سيتم إنشاء أحداث مخصصة على التحكم الخاصة بك، ورفع لهم في الأوقات المناسبة.
والسيناريو الخاص بك هو معقد إلى حد ما، ولكن لا يسمع. (أنا فعلا في وضع مماثل جدا على واحد من مشاريعي الحالية.) الطريق I الاقتراب منه هو أن عنصر تحكم المستخدم هي المسؤولة عن التحقق من صحة الخاصة به. أنا لا أستعمل CausesValidation. بدلا من ذلك في النقطة المناسبة تحكم المستخدم، وإجراء التحقق من الصحة من خلال تجاوز ValidateChildren (). (وهذا يحدث عادة عندما يقوم المستخدم بالنقر على "حفظ" أو "التالي" على عنصر تحكم المستخدم، بالنسبة لي).
لا يكون على دراية بك UI التحكم المستخدم، والتي قد لا تكون 100٪ النهج الصحيح بالنسبة لك. ومع ذلك، إذا قمت برفع أحداث مخصصة (ربما مع EventArgs المخصصة التي تحدد ما إذا كان أو لم يكن لإجراء التحقق من الصحة)، يجب أن تكون قادرا على الحصول على المكان الذي تريد أن تكون.
وسوف تحتاج إلى سلك يصل أحداث يهمك التقاط داخل التحكم الخاصة بك، ونشرها من خلال بعض الخصائص حدث مخصص على عنصر تحكم المستخدم نفسه. ومن شأن مثال بسيط أن التفاف على الحدث انقر على زر:
// CustomControl.cs
// Assumes a Button 'myButton' has been added through the designer
// we need a delegate definition to type our event
public delegate void ButtonClickHandler(object sender, EventArgs e);
// declare the public event that other classes can subscribe to
public event ButtonClickHandler ButtonClickEvent;
// wire up the internal button click event to trigger our custom event
this.myButton.Click += new System.EventHandler(this.myButton_Click);
public void myButton_Click(object sender, EventArgs e)
{
if (ButtonClickEvent != null)
{
ButtonClickEvent(sender, e);
}
}
وبعد ذلك، في النموذج الذي يستخدم تلك السيطرة، وكنت سلك يصل الحدث وكأنك أي دولة أخرى:
// CustomForm.cs
// Assumes a CustomControl 'myCustomControl' has been added through the desinger
this.myCustomControl.ButtonClickEvent += new System.EventHandler(this.myCustomControl_ButtonClickEvent);
myCustomControl_ButtonClickEvent(object sender, EventArgs e)
{
// do something with the newly bubbled event
}
في حالة شخص لا يزال يتساءل كيف لمحاكاة الحدث محتدما في WinForm طريقة <لأ href = "https://msdn.microsoft.com/en-us/library/system.windows.forms.application.addmessagefilter(v = vs.110) .aspx اتصال "يختلط =" نوفولو "> Application.AddMessageFilter هو مكان جيد للنظر في.
وباستخدام هذه الطريقة يمكنك تثبيت الفلتر الخاصة بها والتي تراقب كل الرسائل على نشرها لقائمة انتظار الرسائل للموضوع الحالي.
ويجب عليك أن تدرك أن الرسائل التي يتم إرسالها (لم تنشر) لا يمكن التعامل معها عن طريق هذا الفلتر. Fourtounatly، يتم نشر الأحداث الأكثر إثارة للاهتمام (مثل النقر الأحداث) ولم ترسل، وبالتالي يمكن رصدها من خلال هذا الفلتر
وأود أن تتناغم في ذلك، كما وصفها، يبدو فعلا وكأنك مطاردة ذر الرماد في العيون. في حين يبدو أن لديك الحالة التي يكون فيها عدم وجود الحدث محتدما في WinForms عناصر يسبب لك المتاعب، فإن الواقع هو أن بنية الفقيرة يجبرك إلى الحاجة محتدما الحدث عند لا ينبغي.
إذا يمكنك ريفاكتور / إعادة هيكلة التصميم الخاص بك مثل أن الضوابط تعمل مع نموذج بيانات المشترك (MVC / MVP هي الخيارات واضحة) ثم يمكنك ببساطة تطبيق WinForms عناصر الأنماط الشائعة مثل أحداث PropertyChanged على نموذج لنقول النموذج الرئيسي و أي عناصر التحكم الأخرى التي تستهلك تلك البيانات لتحديث نفسها.
وباختصار، فإن إجابات أخرى معقولة من حيث أنها تجيب على سؤال حول ما طلب منها ذلك. ولكن من وجهة نظر رمز الجودة، وأعتقد أن الجواب الأفضل هو فصل البيانات من واجهة المستخدم.