2010-03-02 10 views
11

मैं UserControl से व्युत्पन्न एक कस्टम नियंत्रण बना रहा हूं जिसे मैं फोकस करना चाहता हूं।एक .NET UserControl पर फ़ोकस सेट करना ...?

कस्टम नियंत्रण में कॉम्बोबॉक्स नियंत्रण होता है और मैं इसके बगल में कुछ तार खींचता हूं।

ComboBox फोकस प्राप्त कर सकते हैं, लेकिन मैं UserControl ही फोकस सेट करने में सक्षम होना चाहते हैं। मेरा ऑनपेंट हैंडलर नियंत्रण को थोड़ा अलग तरीके से खींचने के लिए स्थापित किया गया है यदि यह फोकस करता है लेकिन जब मैं अपना कस्टम नियंत्रण बनाता हूं तो मैं कैनफ़ोकस() को मूल रूप से कॉल करता हूं और यह झूठा रिटर्न देता है।

क्या कोई संपत्ति या सेट करने के लिए कुछ है?

उत्तर

21

उपयोगकर्ता नियंत्रण आपको फोकस से बचने के लिए दांत और नाखून से लड़ेंगे। इसमें कोड है जो फोकस प्राप्त करने पर स्वचालित रूप से एक बच्चे के नियंत्रण (यदि कोई हो) पर ध्यान केंद्रित करता है। आपको कम से कम WndProc() को ओवरराइड करना होगा और WM_SETFOCUS संदेश को जाल करना होगा। अन्य सर्जरी की आवश्यकता हो सकती है, जैसे ControlStyles.Selectable और TabStop और TabIndex गुण।

आपका अगला मुद्दा यह है कि UserControl करने के लिए, कहते हैं, कीबोर्ड संदेशों सार्थक जवाब नहीं होगा जब यह ध्यान केंद्रित किया है। आपको माउस संदेशों को संभालने के लिए यूसी पृष्ठभूमि पर क्लिक का पता लगाने की आवश्यकता होगी, साथ ही चित्रकला को ओवरराइड करें ताकि उपयोगकर्ता के लिए यह स्पष्ट हो कि यूसी का ध्यान केंद्रित है (ControlPaint.DrawFocusRectangle का उपयोग करें)। अगर यह अवांछित लगना शुरू हो जाता है, तो ऐसा इसलिए होता है क्योंकि यूसी वास्तव में एक कंटेनर नियंत्रण होने के लिए था।

+1

यह नौकरी करना प्रतीत होता था। आपके द्वारा उल्लिखित जटिलताओं को हल करने के लिए मैं इसके साथ खेलना जारी रखूंगा। धन्यवाद! – Sambo

+1

+1 NoBugz से एक और बड़ा जवाब पाने के लिए खुशी हुई। उत्सुक: इस मामले में क्या आपको लगता है कि ओपी उपयोगकर्ता नियंत्रण के बजाए फॉर्म का उपयोग करके बेहतर कर सकता है? – BillW

+2

@ बिल: फॉर्म क्लास एक कंटेनर नियंत्रण भी है, हालांकि यह बिल्कुल उसी तरह से लड़ नहीं पाएगा। गैर-मानक यूआई प्रथाओं से बचने के लिए मेरी सलाह होगी। यह उपयोगकर्ता को भी भ्रमित करता है। –

1

एक नियंत्रण के लिए http://msdn.microsoft.com/en-us/library/system.windows.forms.control.canfocus.aspx

टिप्पणियां

आदेश में से इनपुट फ़ोकस प्राप्त करने के लिए, नियंत्रण एक संभाल में डाला गया, और दर्शनीय होना आवश्यक है और सक्षम गुण दोनों चाहिए दोनों नियंत्रण और सब अपनी मूल नियंत्रण के लिए सही पर सेट किया जा सकता, और नियंत्रण एक रूप या शेष भाग में होना चाहिए रोल का बाहरीतम माता-पिता फ़ॉर्म होना चाहिए।

सुनिश्चित करें कि आप इन prerequesits को पूरा किया है।

+1

आपकी प्रतिक्रिया के लिए धन्यवाद ... मैंने पुष्टि की है कि मेरे नियंत्रण में हैंडल के लिए एक मूल्य है। नियंत्रण दृश्यमान और सक्षम भी है और जिस पैनल को मैं इसे अंदर प्रदर्शित करता हूं वह दृश्यमान और सक्षम भी है ... और यह सब एक फॉर्म पर दिखाई देता है ...! ऐसा लगता है कि पूर्व-आवश्यकताएं मिलती हैं ... मैंने ऑनगॉटफोकस() को ओवरराइड किया और ब्रेकपॉइंट सेट किया लेकिन यह कभी हिट नहीं हुआ। इसके अलावा, मैंने अपने फॉर्म ऑब्जेक्ट में नियंत्रण के गॉटफोकस ईवेंट के लिए एक हैंडलर स्थापित किया और, एक बार फिर, कोड कभी हिट नहीं हुआ। कोई अन्य विचार ...? – Sambo

+0

ये पूर्वापेक्षाएँ नियंत्रण पर लागू होती हैं, लेकिन UserControl इसे उपरोक्त वर्णित @ हंसपैसेंट के रूप में छेड़छाड़ करता है। –

1

एक टिप्पणी के लिए बहुत लंबा, लिंक, और कोड भी शामिल है ... लेकिन यह एक टिप्पणी है ...

बहुत से लोग 'GotFocus() घटना फायरिंग नहीं एक UserControl के बारे में शिकायत की है। उदाहरण के लिए: UserControl and GotFocus() fyi: LostFocus() मेरे अनुभव में अपेक्षित रूप से आग लग जाएगा। अतीत में, एक से अधिक फार्म परियोजना में, मैं को लागू करने के साथ प्रयोग किया गया है 'दर्ज करें और' प्रत्येक फार्म पर एक UserControl पर ईवेंट हैंडलर्स छोड़ दो, और पाया कि 'एंटर केवल फार्म लोड पर कहा जाता है, एक बार।

जाहिर UserControl "फोकस ले" पर नियंत्रण (एक तरह से मैं व्याख्या नहीं कर सकते में, लेकिन शायद तो चलो WinForms गुरुओं में से एक होगा)। शायद यह इस तथ्य से संबंधित है कि UserControl ContainerControl से निकलता है?लोड घटना: 'UserControl में

private void Control_GotFocus(object sender, EventArgs e) 
    { 
     Console.WriteLine("Control GotFocus : " + ((sender as Control).Name)); 
    } 

और फिर, GotFocus() हैंडलर', कि ईवेंट हैंडलर को UserControl पर सभी नियंत्रण ऊपर वायर्ड:

मैं एक लेखन के साथ प्रयोग किया है जो मैं ने कहा कि था सबसे कम TabIndex के साथ UserControl पर नियंत्रण 'ऐप लॉन्च करने और फॉर्म के बीच स्विच करने पर' गॉटफोकस ईवेंट को आग लगा देगा।

इस स्थिति में मैंने जो एक और चीज देखी है, यह सुनिश्चित करना है कि 'UserControl की IsTabStop प्रॉपर्टी' पर सेट है, यह सच है: यह सिल्वरलाइट से संबंधित प्रश्न के संदर्भ में एमएस में शॉन वाइल्डर्मथ से था, इसलिए कोई फर्क नहीं पड़ता कि यह आपके मामले में लागू हो सकता है।

एक और सुझाव, जो उपयोगकर्ता नियंत्रण के लिए माउसडाउन या माउसक्लिक ईवेंट हैंडलर लिखना था, और उस कॉल में: this.SetFocus(); ने मुझे कहीं भी नेतृत्व नहीं किया।

आशा है कि आपको उत्तर मिलेगा!

1

कुछ मामलों में यह भी ध्यान केंद्रित करने योग्य है कि फोकस उपयोगकर्ता नियंत्रण के बाल तत्वों को स्थानांतरित न करें।
इस मामले में आपको भी नियंत्रण के लिए ControlStyles.ContainerControl सेट करने की आवश्यकता है।

Public Sub New() 
    InitializeComponent() 

    Me.SetStyle(ControlStyles.ContainerControl, False) 
    Me.SetStyle(ControlStyles.Selectable, True) 

End Sub 
0

कहते हैं, आप अपने उपयोगकर्ता नियंत्रण पर एक चित्र है और आप "GetFocus" घटना की नकल उतार यह उजागर करने के लिए (जैसे कि अपने उपयोगकर्ता नियंत्रण पर ध्यान केंद्रित इस तस्वीर लेता है) चाहते हैं। आपके उपयोगकर्ता नियंत्रण पर फोकस पिक्चरबॉक्स में एक रूपरेखा डैश लाइन को चित्रित करके संभाला जाएगा। यह आपके उपयोगकर्ता नियंत्रण OnEnter और OnLeave घटनाओं के माध्यम से किया जाता है। यहां हाइलाइट प्रक्रिया है ...

Public Sub highlightImage() 
    Dim l As Single() = {2, 2, 2, 2} 
    Dim p As New Pen(Color.Gray, 1) 
    p.DashPattern = l 
    Dim g As Graphics = picColor.CreateGraphics() 
    g.DrawRectangle(p, 0, 0, picColor.Width - 1, picColor.Height - 1) 
End Sub 

ये दो ओवरराइड नौकरी करेंगे।

Protected Overrides Sub OnEnter(e As EventArgs) 
    MyBase.OnEnter(e) 
    Me.highlightImage() 
End Sub 
Protected Overrides Sub OnLeave(e As EventArgs) 
    MyBase.OnLeave(e) 
    MyBase.Refresh() 
End Sub 
0

UserControl फोकस हो जाता है, यह आंतरिक रूप से अपने बच्चे को नियंत्रित करने के लिए ध्यान केंद्रित करने से गुजरता है।

तो आपको कोड के निष्पादन को छोड़ना होगा जो बाल नियंत्रण पर ध्यान केंद्रित करता है। इसके लिए आपको किसी भी WM_SETFOCUS संदेश के WNDProc() को निष्पादित करने की आवश्यकता होगी।

public class FocusableUserControl : UserControl 
{ 
    protected override void WndProc(ref Message m) 
    { 
     switch (m.Msg) 
     { 
      case (int)Win32Constants.WM_SETFOCUS: 
      //Returning from here will skip setting focus to child controls. 
      //It will not skip setting focus to this control. 

       Console.WriteLine("FocusableUserControl is focused: " + Focused); 
       return; 
     } 

     base.WndProc(ref m); 
    } 
} 

जहां WM_SETFOCUS "0x0007" है।

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