سؤال

البيئة: .NET Framework 2.0، مقابل 2008.

أحاول إنشاء فئة فرعية من بعض عناصر تحكم .NET (الملصقات، لوحة) التي ستمر عبر أحداث الماوس معينة (MouseDown, MouseMove, MouseUp) إلى عنصر تحكم الوالدين (أو بدلا من ذلك إلى نموذج المستوى الأعلى). يمكنني القيام بذلك عن طريق إنشاء معالجات لهذه الأحداث في مثيلات الضوابط القياسية، على سبيل المثال:

public class TheForm : Form
{
    private Label theLabel;

    private void InitializeComponent()
    {
        theLabel = new Label();
        theLabel.MouseDown += new MouseEventHandler(theLabel_MouseDown);
    }

    private void theLabel_MouseDown(object sender, MouseEventArgs e)
    {
        int xTrans = e.X + this.Location.X;
        int yTrans = e.Y + this.Location.Y;
        MouseEventArgs eTrans = new MouseEventArgs(e.Button, e.Clicks, xTrans, yTrans, e.Delta);
        this.OnMouseDown(eTrans);
    }
}

لا يمكنني نقل معالج الأحداث في فئة فرعية من عنصر التحكم، لأن الأساليب التي ترفع الأحداث في عنصر تحكم الأصل محمي وليس لدي مؤهل للتحكم الرئيسي:

لا يمكن الوصول إلى العضو المحمي System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs) عبر تصفية من النوع System.Windows.Forms.Control; ؛ يجب أن يكون التصفيات من النوع TheProject.NoCaptureLabel (أو مشتقة منه).

أنا أبحث في تجاوز WndProc طريقة التحكم في فئتي الفرعية، ولكن نأمل أن يعطيني شخص ما حلا نظيفا.

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

المحلول

نعم. بعد الكثير من البحث، وجدت المقال "الضوابط العائمة، نمط Tooltip", ، والتي تستخدم WndProc لتغيير الرسالة من WM_NCHITTEST ل HTTRANSPARENT, ، جعل Control شفافة لأحداث الماوس.

لتحقيق ذلك، قم بإنشاء عنصر تحكم موروث من Label وبما هو إضافة التعليمات البرمجية التالية.

protected override void WndProc(ref Message m)
{
    const int WM_NCHITTEST = 0x0084;
    const int HTTRANSPARENT = (-1);

    if (m.Msg == WM_NCHITTEST)
    {
        m.Result = (IntPtr)HTTRANSPARENT;
    }
    else
    {
        base.WndProc(ref m);
    }
}

لقد اختبرت هذا في Visual Studio 2010 مع ملف تعريف .NET Framework 4.

نصائح أخرى

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

أو

هل هذا ما تريد؟

public class MyLabel : Label
{
    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        //Do derived class stuff here
    }
}

ال WS_EX_TRANSPARENT نمط النافذة الممتدة فعلا يفعل هذا (فهو استخدام Tooltips في مكان). قد ترغب في التفكير في تطبيق هذا النمط بدلا من الترميز الكثير من المعالجين للقيام بذلك من أجلك.

للقيام بذلك، تجاوز CreateParams طريقة:

protected override CreateParams CreateParams
{
  get
  {
    CreateParams cp=base.CreateParams;
    cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
    return cp;
  }
}

لمزيد من القراءة:

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