WPF: कैसे एक TextBox से प्रोग्रामेटिक रूप से ध्यान हटाने के लिए


95

मैं अपने WPF के लिए एक सरल (कम से कम मुझे लगा कि यह व्यवहार था) जोड़ना चाहता हूं TextBox

जब उपयोगकर्ता बचता है तो मैं चाहता हूं कि TextBoxवह उस पाठ को संपादित करना चाहता है, जब उपयोगकर्ता ने संपादन शुरू किया था, और मैं उस पर ध्यान हटाना चाहता हूं TextBox

मेरे पास संपादन की शुरुआत में इसके मूल्य के लिए पाठ सेट करने में कोई समस्या नहीं है।

समस्या तत्व का ध्यान हटाने के लिए है। मैं फ़ोकस को किसी अन्य घटक में स्थानांतरित नहीं करना चाहता, मैं केवल TextBoxफ़ोकस खोना चाहता हूं । क्या मेरे पास फ़ोकस सेट करने के लिए एक अदृश्य तत्व होना चाहिए ताकि मेरा TextBoxफ़ोकस खो सके?

जवाबों:


152

.NET फ्रेमवर्क 4 में Keyboard.ClearFocus();


1
यह वही था जो मैं इस शाम की तलाश में था!
जोश

9
यह हमेशा ध्यान केंद्रित नहीं करता है: मुझे एक समस्या है जहां एक लिस्टबॉक्स के अंदर एक AutoCompleteTextBox Keyboard.ClearFocus()कहीं एक क्लिक के बाद कोड-पीछे से चलने पर ध्यान केंद्रित नहीं करता है।
एव्स जूल

3
ClearFocusGotFocusहाल ही में केंद्रित नियंत्रण के लिए आग न लगाने का कारण है जबकि यह अभी भी अन्य नियंत्रणों के लिए आग है। उदाहरण के लिए, मेरे कस्टम ऑनस्क्रीन कीबोर्ड के लिए यह एक बड़ी समस्या है। यह कैरेट को गायब करने का कारण बनता है, जो संभवतः "कीबोर्ड फ़ोकस" होता है। शायद मुझे "माउस फ़ोकस" जैसी किसी चीज़ में ज़्यादा दिलचस्पी है।
ग्रास

2
शुक्रिया ग्रेगुल, मुझे भी यही समस्या हुई। सबसे अच्छा जो मैं लेकर आया हूं, वह है फोकस को किसी अन्य नियंत्रण के साथ स्थानांतरित करना other.Focus()
टोर क्लिंगबर्ग

7
@Grault यह केवल कीबोर्ड फ़ोकस को साफ़ करता है, न कि लॉजिकल फ़ोकस (जो कि GotFocusईवेंट को आग लगाता है )। आपके कार्यक्रम में हमेशा तार्किक फोकस के साथ कुछ होता है। LostKeyboardFocusकीबोर्ड फोकस क्लियर करने से पहले या तो इवेंट या शिफ्ट फ़ोकस का उपयोग दूसरे तत्व (जो इसके साथ लॉजिकल फ़ोकस को शिफ्ट करता है) का उपयोग करें।
चिरिमोरिन

54

मैं जिस कोड का उपयोग कर रहा हूं:

// Move to a parent that can take focus
FrameworkElement parent = (FrameworkElement)textBox.Parent;
while (parent != null && parent is IInputElement && !((IInputElement)parent).Focusable)
{
    parent = (FrameworkElement)parent.Parent;
}

DependencyObject scope = FocusManager.GetFocusScope(textBox);
FocusManager.SetFocusedElement(scope, parent as IInputElement);

2
यह कोड बहुत अच्छा है, Keyboard.ClearFocus () के कुछ अनपेक्षित दुष्प्रभाव हैं
patrick

क्यों हालत! ((IInputElement) माता-पिता)। सामने? यदि माता-पिता ध्यान देने योग्य हैं तो क्या यह स्थिति सही नहीं होनी चाहिए?
मर्ट अक्काया

Mert - निश्चित नहीं है, लेकिन इस पोस्ट के माध्यम से ब्राउज़ करने पर ऐसा लगता है कि जब तक यह सही नहीं है, तब तक इसे जारी रखें। इस तरह पहला ध्यान देने योग्य आइटम लूप को समाप्त करता है।
जिपरसन

4
@ पेप्ट्रिक, जो अनपेक्षित साइड इफेक्ट्स हैं? क्या आप प्रासंगिक उदाहरण दे सकते हैं?
एवेज़

1
यह एक बेहतरीन उपाय है। मुझे Keyboard.ClearFocus () के साथ भी समस्या थी। मोडल विंडो के अंदर एक टेक्स्टबॉक्स पर ClearFocus () चलाते समय, यह टेक्स्टबॉक्स और विंडो दोनों को फोकस खोने का कारण बनता है। मतलब कीडाउन इवेंट अब विंडो में नहीं जाते हैं। इसके बजाय इसे बदलने से फ़ोकस एक माता-पिता (जो विंडो हो सकता है) में बदल जाता है, भविष्य के कीडाउन ईवेंट गुम नहीं होते हैं। मेरे व्यावहारिक उदाहरण में, मेरे पास "Key.Escape" और कॉलिंग क्लोज़ () की तलाश में विंडो है। यदि आप कहीं भी ClearFocus () चलाते हैं तो यह काम करना बंद कर देता है।
डेनिस पी

19

पार्टी में थोड़ी देर हो गई, लेकिन यह मेरे लिए मददगार था इसलिए यहाँ जाता है।

.Net 3.0 के बाद से, FrameworkElementएक MoveFocus फ़ंक्शन है, जिसने मेरे लिए चाल चली


निर्देशों के लिए -> msdn.microsoft.com/en-us/library/…
कार्टर मेडलिन

"सुनिश्चित करें कि आप इस विधि के रिटर्न मूल्य की जांच करते हैं। यदि ट्रावर्सल एक टैब स्टॉप में चलता है जो नियंत्रण की संरचना द्वारा परिभाषित किया गया है, और ट्रैवर्सल अनुरोध ने रैप करने का अनुरोध नहीं किया है तो झूठ का रिटर्न मूल्य वापस आ सकता है।" - msdn.microsoft.com/en-us/library/…
aderesh

13

चूँकि उपर्युक्त उत्तरों में से किसी ने भी मेरे लिए काम नहीं किया और स्वीकृत उत्तर केवल कीबोर्ड फ़ोकस के लिए काम करता है, इसलिए मैं निम्नलिखित दृष्टिकोण पर आया:

// Kill logical focus
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null);
// Kill keyboard focus
Keyboard.ClearFocus();

दोनों को मारता है, तार्किक और साथ ही कीबोर्ड फोकस।


9

आप फ़ोकस को फ़ोकस करने योग्य पूर्वज पर सेट कर सकते हैं। यह कोड तब भी काम करेगा, जब टेक्स्टबॉक्स किसी टेम्पलेट के अंदर हो, जिसमें समान टेम्पलेट के अंदर कोई फोकस करने योग्य पूर्वज न हों:

DependencyObject ancestor = textbox.Parent;
while (ancestor != null)
{
    var element = ancestor as UIElement;
    if (element != null && element.Focusable)
    {
        element.Focus();
        break;
    }

    ancestor = VisualTreeHelper.GetParent(ancestor);
}

6

AFAIK, फोकस को पूरी तरह से हटाना संभव नहीं है। आपके विंडो में कुछ हमेशा फोकस रहेगा।


2

विंडोज फोन डेवलपमेंट में, मैंने अभी-अभी Focus()या PhoneApplicationPagethis.Focus() में किया था और इसने एक आकर्षण की तरह काम किया।


1

मेरे लिए, यह काफी पेचीदा है, खासकर जब लॉस्टफोकस बाइंडिंग के साथ उपयोग किया जाता है। हालाँकि, मेरा काम एक खाली लेबल जोड़ना और उस पर ध्यान केंद्रित करना है।

<Label Name="ResetFocusArea" Focusable="True" FocusVisualStyle="{x:Null}" />

...

OnKeyDown(object sender, RoutedEventArgs e)
{
  //if is Esc
  ResetFocusArea.Focus();
}

0

मेरा उत्तर सीधे ऊपर के प्रश्न को स्वीकार नहीं करता है, हालाँकि, मुझे लगता है कि इसका शब्दांकन इसके कारण "द क्वेश्चन" बन गया है, जो प्रोग्रामेटिक रूप से फ़ोकस से छुटकारा दिलाता है। एक सामान्य परिदृश्य जहां इसकी आवश्यकता होती है, उपयोगकर्ता के लिए विंडो की तरह रूट कंट्रोल की पृष्ठभूमि पर क्लिक करने पर ध्यान केंद्रित करने में सक्षम होना चाहिए।

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

public class LoseFocusOnLeftClick : Behavior<FrameworkElement>
{
    private readonly MouseBinding _leftClick;
    private readonly Label _emptyControl = new Label() { Focusable = true, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top };

    public LoseFocusOnLeftClick()
    {
        _leftClick = new MouseBinding(new RelayCommand(LoseFocus), new MouseGesture(MouseAction.LeftClick));
    }

    protected override void OnAttached()
    {
        AssociatedObject.InputBindings.Add(_leftClick);
        AssociatedObject.Loaded += AssociatedObject_Loaded;
    }        

    protected override void OnDetaching()
    {
        AssociatedObject.InputBindings.Remove(_leftClick);
        AssociatedObject.Loaded -= AssociatedObject_Loaded;
    }

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        AssociatedObject.Loaded -= AssociatedObject_Loaded;

        AttachEmptyControl();
    }

    private void AttachEmptyControl()
    {            
        DependencyObject currentElement = AssociatedObject;
        while (!(currentElement is Panel))
        {
            currentElement = VisualTreeHelper.GetChild(currentElement, 0);
        }

        ((Panel)currentElement).Children.Add(_emptyControl);
    }

    private void LoseFocus()
    {            
        _emptyControl.Focus();
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.