هل تريد استدعاء أحداث C# من خارج فئة المالك؟

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

  •  01-07-2019
  •  | 
  •  

سؤال

هل من الممكن تحت أي مجموعة من الظروف أن تكون قادرًا على تحقيق ذلك؟

ظروفي الحالية هي:

public class CustomForm : Form
{
    public class CustomGUIElement
    {
    ...
        public event MouseEventHandler Click;
        // etc, and so forth.
    ...
    }

    private List<CustomGUIElement> _elements;

    ...

    public void CustomForm_Click(object sender, MouseEventArgs e)
    {
        // we might want to call one of the _elements[n].Click in here
        // but we can't because we aren't in the same class.
    }
}

كانت فكرتي الأولى هي الحصول على وظيفة مشابهة لما يلي:

internal enum GUIElementHandlers { Click, ... }
internal void CustomGUIElement::CallHandler(GUIElementHandler h, object[] args) {
    switch (h) {
        case Click:
            this.Click(this, (EventArgs)args[0]);
            break;
        ... // etc and so forth
    }
}

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

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

المحلول

تحتاج فقط إلى إضافة طريقة عامة لاستدعاء الحدث.تقوم Microsoft بذلك بالفعل لبعض الأحداث مثل انقر فوق للضوابط التي تعرض أ انقر حدث.

public class CustomGUIElement    
{
    public void PerformClick()
    {
        OnClick(EventArgs.Empty);
    }

    protected virtual void OnClick(EventArgs e)
    {
        if (Click != null)
            Click(this, e);
    }
}

ستقوم بعد ذلك بما يلي داخل معالج الأحداث الخاص بك ...

public void CustomForm_Click(object sender, MouseEventArgs e)        
{
    _elements[0].PerformClick();
}

نصائح أخرى

تقوم الكلمة الأساسية للحدث في c# بتعديل إعلان المفوض.يمنع التعيين المباشر للمفوض (يمكنك فقط استخدام += و-= في الحدث)، ويمنع استدعاء المفوض من خارج الفصل.

لذلك يمكنك تغيير الكود الخاص بك ليبدو كما يلي:

public class CustomGUIElement
{
...
    public MouseEventHandler Click;
    // etc, and so forth.
...
}

ثم يمكنك استدعاء الحدث من خارج الفصل مثل هذا.

myCustomGUIElement.Click(sender,args);

العيب هو أن الكود الذي يستخدم الفصل يمكنه الكتابة فوق أي معالجات مسجلة بسهولة شديدة باستخدام كود مثل هذا:

myCustomGUIElement.Click = null;

وهو أمر غير مسموح به إذا تم الإعلان عن مندوب النقر كحدث.

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

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