2009-02-13 6 views
29

पर्यावरण: .NET फ्रेमवर्क 2.0, वी.एस. 2008हस्तांतरण की माउस माता पिता नियंत्रण करने के लिए घटनाओं

मैं कुछ नेट नियंत्रण (लेबल, पैनल) उस विशिष्ट माउस घटनाओं के माध्यम से पारित करेंगे की एक उपवर्ग बनाने के लिए कोशिश कर रहा हूँ (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 के क्वालीफायर के माध्यम से संरक्षित सदस्य System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs) तक नहीं पहुंच सकता; क्वालीफायर TheProject.NoCaptureLabel (या इससे व्युत्पन्न) होना चाहिए।

मैं अपने उप-वर्ग में नियंत्रण की WndProc विधि अधिभावी में देख रहा हूँ, लेकिन उम्मीद है कि किसी ने मुझे एक क्लीनर समाधान दे सकते हैं।

+0

क्या यह इस कोड के लिए सही त्रुटि संदेश है? एक माउसअप है दूसरा माउसडाउन है। –

+0

यह मेरे लिए कुछ हद तक अस्पष्ट भी है जिसका अर्थ है "पास से"। –

+0

त्रुटि संदेश गलत है, यह माउसडाउन होना चाहिए। मेरा मतलब है "पास से" का अर्थ यह है कि, जब कुछ घटनाएं नियंत्रण पर उठाई जाती हैं, तो मैं उन्हें नियंत्रण के माता-पिता पर प्रोग्रामेटिक रूप से बढ़ाता हूं। – GentlemanCoder

उत्तर

55

हां। बहुत सारी खोज के बाद, मुझे आलेख मिला, जो WM_NCHITTEST से HTTRANSPARENT से संदेश बदलने के लिए WndProc का उपयोग करता है, जिससे 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); 
    } 
} 

मैंने विजुअल स्टूडियो 2010 में .NET Framework 4 क्लाइंट प्रोफाइल के साथ इसका परीक्षण किया है।

+0

धन्यवाद अकरान - मैं अब तक चले गए हैं, मुझे यह भी याद नहीं है कि मैंने इस मुद्दे को कैसे हल किया है, लेकिन ऐसा लगता है कि आपने इसे खींचा है। – GentlemanCoder

+0

बहुत बहुत धन्यवाद, इससे मुझे मदद मिली - स्पष्ट, संक्षिप्त, और समस्या हल करती है! – Eric

+1

यह ध्यान देने योग्य है कि यह घटना लूप से झूठे पारदर्शी नियंत्रण लेता है - उन्हें माउसमोव ईवेंट को स्वयं संभालने का मौका नहीं मिलता है क्योंकि यह सीधे माता-पिता के हैंडलर पर ड्रिल करता है। प्रत्येक नियंत्रण के लिए क्षमता को बनाए रखने के लिए माता-पिता को पास करने से पहले ईवेंट को संभालने के लिए आप कुछ ऐसा कर सकते हैं: http://stackoverflow.com/a/14814756/327083 –

3

आपको अपनी बेस क्लास में एक सार्वजनिक/संरक्षित विधि लिखनी होगी जो आपके लिए ईवेंट बढ़ाएगी। फिर व्युत्पन्न कक्षा से इस विधि को बुलाओ।

या

क्या आप यह चाहते हैं?

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

मुझे ऐसा नहीं लगता है। OnMouseDown * घटना * उठाता है, यह इसे संभाल नहीं करता है। मुझे एक इवेंट हैंडलर चाहिए जो इस घटना को अपने माता-पिता को पास करता है। और मैं आपका पहला सुझाव नहीं कर सकता बी/सी बेस क्लास एक मानक विंडोज नियंत्रण है, न कि मैंने जो कक्षा लिखी है। – GentlemanCoder

+0

@GentlemanCoder क्या आपने वास्तव में यह कोशिश की है? –

+0

@ संदीप दत्ता, अभिभावक नियंत्रण और आधार वर्ग अलग हैं, है ना? – Kira

3

WS_EX_TRANSPARENT विस्तारित खिड़की शैली वास्तव में करता है यह (यह क्या यथा-स्थान टूलटिप्स का उपयोग है)। हो सकता है कि आप अपने लिए ऐसा करने के लिए बहुत सारे हैंडलर कोडिंग करने के बजाय इस शैली को लागू करने पर विचार करना चाहें।

ऐसा करने के लिए, CreateParams विधि ओवरराइड:

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

आगे पढ़ने के लिए:

+1

सुझाव के लिए धन्यवाद। मैंने कोशिश की और यह मेरे मामले में काम नहीं करता है। शायद यह केवल शीर्ष स्तर की खिड़कियों के लिए काम करता है? – GentlemanCoder

संबंधित मुद्दे