WPF TextBox में फोकस पर सभी टेक्स्ट को स्वचालित रूप से कैसे चुनें?


232

अगर मैं SelectAllकिसी GotFocusईवेंट हैंडलर से कॉल करता हूं , तो यह माउस के साथ काम नहीं करता है - जैसे ही माउस रिलीज़ होता है, चयन गायब हो जाता है।

EDIT: लोग डोनले के जवाब को पसंद कर रहे हैं, मैं यह समझाने की कोशिश करूंगा कि मुझे यह उतना पसंद क्यों नहीं आया जितना स्वीकार किया गया जवाब।

  • यह अधिक जटिल है, जबकि स्वीकृत उत्तर एक ही कार्य को सरल तरीके से करता है।
  • स्वीकृत उत्तर की प्रयोज्यता बेहतर है। जब आप पाठ के बीच में क्लिक करते हैं, तो जब आप माउस को तुरंत संपादन शुरू करने की अनुमति देते हैं, तो पाठ अचयनित हो जाता है, और यदि आप अभी भी सभी का चयन करना चाहते हैं, तो बस फिर से बटन दबाएं और इस बार यह रिलीज पर अचयनित नहीं होगा। डोनेल की रेसिपी के बाद, अगर मैं टेक्स्ट के बीच में क्लिक करता हूं, तो मुझे दूसरी बार क्लिक करना होगा ताकि एडिट कर सकें। यदि मैं पाठ के भीतर बनाम पाठ के बाहर कहीं क्लिक करता हूं, तो इसका सबसे अधिक अर्थ है कि मैं सब कुछ अधिलेखित करने के बजाय संपादन शुरू करना चाहता हूं।

यदि आपके पास एक से अधिक फॉर्म होने वाले हैं, तो उसका जवाब पहले की तुलना में कम जटिल हो जाता है। दोनों विकल्पों की प्रयोज्यता लूट है क्योंकि आप बदल सकते हैं कि उनमें से कोई भी कैसे काम करता है।
Thepaulpage

1
@ सेर्गेई: आप इस प्रश्न के लिए स्वीकृत उत्तर को बदलना चाह सकते हैं, क्योंकि इसमें बेहतर उत्तर दिए गए हैं। मैं मेरा सुझाव नहीं देने जा रहा हूं, लेकिन आप कर सकते हैं;)
Grokys

प्रश्न में सिल्वरलाइट टैग है, फिर भी सिल्वरलाइट में ज्यादातर इवेंट्स / किसी भी तरह के प्रीव्यू इवेंट्स नहीं होते हैं। सिल्वरलाइट के लिए कौन सा घोल इस्तेमाल किया जाना चाहिए?
वैलेंटाइन कुजब

लिंक "WPF में ध्यान केंद्रित करना इतना मुश्किल क्यों है?" टूट गया है
मैक्सेंस

1
जैसा कि नीचे stackoverflow.com/a/2553297/492 पर एक टिप्पणी में उल्लेख किया गया है , madprops.org/blog/wpf-textbox-selectall-on-focus एक आसान उपाय है और मूल संज्ञा व्यवहार को संरक्षित करता है। मैंने कंस्ट्रक्टर में ईवेंट पंजीकरण रखा क्योंकि मेरे पास ऐप में केवल एक WPF नियंत्रण है।
सीएडी

जवाबों:


75

पता नहीं क्यों यह GotFocusघटना में चयन खो देता है ।

लेकिन एक समाधान के लिए GotKeyboardFocusऔर GotMouseCaptureघटनाओं पर चयन करना है । इस तरह यह हमेशा काम करेगा।


10
नहीं। जब मौजूदा पाठ के बीच में माउस के साथ क्लिक किया जाता है - माउस बटन जारी होते ही चयन खो जाता है।
सेर्गेई अल्दखोव

3
हालाँकि - एक दूसरे एकल क्लिक के बाद, यह फिर से सभी पाठ का चयन करता है ... निश्चित नहीं है कि यह WPF डिजाइनरों से एक इच्छित व्यवहार है, लेकिन प्रयोज्य उतना बुरा नहीं है। एक गॉटफोकस हैंडलर से एक और अंतर यह है कि टेक्स्टबॉक्स में खाली जगह पर क्लिक करने से सभी का चयन होता है।
सेर्गेई अल्दखोव

3
यह मेरा मुट्ठी का हल भी था। लेकिन मैंने पाया कि उपयोगकर्ता वास्तव में नाराज होते हैं, जब वे माउस का उपयोग करके पाठ का चयन करने में असमर्थ होते हैं, क्योंकि हर बार जब वे पूरे पाठ पर क्लिक करते हैं तो उनका चयन हो जाता है ...
Nils

1
इस समाधान का एक और दोष यह है कि जब आप TextBox के "कट / कॉपी / पेस्ट" मेनू का उपयोग करते हैं, तो किसी भी मेनू आइटम का चयन करते समय पूरे पाठ का चयन किया जाता है।

@ मुझे पता है कि यह पुराना है, लेकिन क्या किसी को पता है कि GotFocus घटना में चयनित पाठ क्यों खो गया है? आप इसके बारे में अन्य घटनाओं में काम करने के बारे में सही हैं, हालांकि और यह मेरी पुस्तक में एक पूरी तरह से स्वीकार्य समाधान है।
Feign

210

हमारे पास ऐसा है तो पहला क्लिक सभी का चयन करता है, और दूसरा क्लिक कर्सर पर जाता है (हमारा एप्लिकेशन पेन के साथ टैबलेट पर उपयोग के लिए डिज़ाइन किया गया है)।

आपको यह उपयोगी लग सकता है।

public class ClickSelectTextBox : TextBox
{
    public ClickSelectTextBox()
    {
        AddHandler(PreviewMouseLeftButtonDownEvent, 
          new MouseButtonEventHandler(SelectivelyIgnoreMouseButton), true);
        AddHandler(GotKeyboardFocusEvent, 
          new RoutedEventHandler(SelectAllText), true);
        AddHandler(MouseDoubleClickEvent, 
          new RoutedEventHandler(SelectAllText), true);
    }

    private static void SelectivelyIgnoreMouseButton(object sender, 
                                                     MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focussed, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    private static void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}

9
इसके लिए आपको बहुत धन्यवाद। यह आश्चर्यजनक रूप से काम करता है और यह होना चाहिए स्वीकार किए गए उत्तर IMHO। उपरोक्त कोड तब काम करता है जब टेक्स्टबॉक्स कीबोर्ड या माउस (और स्पष्ट रूप से स्टाइलस) के माध्यम से फोकस प्राप्त करता है। +1
ड्रू नोकें जूं

5
मैंने यहाँ लगभग एक जैसा उत्तर देखा। social.msdn.microsoft.com/Forums/en-US/wpf/thread/… , यह साथ ही साथ काम करता है, यह कभी भी e.OriginalSource का उपयोग नहीं करता है, न ही दृश्य पेड़ के माध्यम से क्रॉल करता है। क्या यह सब करने का कोई फायदा है?
मार्को लुग्लियो

1
बहुत अच्छा काम करता है, लेकिन अगर यह अभी भी माउस के साथ पाठ के चयन की अनुमति देता है, तो यह सही होगा। Google Chrome एड्रेस बार आदर्श प्रणाली का एक आदर्श उदाहरण है: यदि उपयोगकर्ता बिना क्लिक किए और रिलीज़ करता है, तो पूरा टेक्स्ट हाइलाइट हो जाता है। हालाँकि यदि उपयोगकर्ता क्लिक करता है और सूख जाता है, तो ड्रैग टेक्स्ट को सामान्य रूप से सभी का चयन किए बिना चुनता है। SelectAll केवल माउस रिलीज़ पर होता है । मैं फील करूंगा और देखूंगा कि क्या मैं इस डिजाइन को बेहतर बना सकता हूं।
devios1

2
इस समाधान का एक और दोष यह है कि जब आप TextBox के "कट / कॉपी / पेस्ट" मेनू का उपयोग करते हैं, तो किसी भी मेनू आइटम का चयन करते समय पूरे पाठ का चयन किया जाता है।

1
मैंने पाया कि इसे बेहतर बनाने की SelectAllTextविधि में एक अतिरिक्त परीक्षण textBox.IsFocused। जब आप GetKeyboardFocusप्रोग्राम में ऑल्ट-टैबिंग के कारण है , तो आप सभी का चयन नहीं करना चाहते हैं ।
स्कॉट स्टाफ़र्ड

164

डोनेल का जवाब सबसे अच्छा काम करता है, लेकिन इसका इस्तेमाल करने के लिए एक नए वर्ग को प्राप्त करना एक दर्द है।

ऐसा करने के बजाय कि मैं अनुप्रयोग में सभी TextBoxes के लिए App.xaml.cs में हैंडलर पंजीकृत करता हूं। यह मुझे मानक टेक्स्टबॉक्स नियंत्रण के साथ डोनल के उत्तर का उपयोग करने की अनुमति देता है।

अपने App.xaml.cs में निम्न विधियाँ जोड़ें:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e) 
    {
        // Select the text in a TextBox when it receives focus.
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseLeftButtonDownEvent,
            new MouseButtonEventHandler(SelectivelyIgnoreMouseButton));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotKeyboardFocusEvent, 
            new RoutedEventHandler(SelectAllText));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.MouseDoubleClickEvent,
            new RoutedEventHandler(SelectAllText));
        base.OnStartup(e); 
    }

    void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focused, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}

4
: यह एक बहुत अच्छा समाधान है, यह भी मैट हैमिल्टन उम्र से पहले यहाँ वर्णित किया गया था है madprops.org/blog/wpf-textbox-selectall-on-focus
एशले डेविस

'प्राप्त ’,
पाईं

2
धन्यवाद नैट, ठीक किया गया, हालाँकि अपने बचाव में मैं यह कहना चाहूँगा कि वर्तनी की गलतियाँ
डोनल

प्रश्न में सिल्वरलाइट टैग है, फिर भी सिल्वरलाइट में ज्यादातर इवेंट्स / किसी भी तरह के प्रीव्यू इवेंट्स नहीं होते हैं। सिल्वरलाइट के लिए कौन सा घोल इस्तेमाल किया जाना चाहिए? अग्रिम धन्यवाद
वैलेंटिन कुजब

4
"ध्यान केंद्रित वर्तनी अमेरिका में बहुत अधिक सामान्य है; हालांकि, वर्तनी की फोकल कभी-कभी यूके और कनाडा में उपयोग की जाती है, और विशेष रूप से ऑस्ट्रेलिया और न्यूजीलैंड में आम है।" तो निआह;)
डोनल

85

यह बल्कि पुराना है, लेकिन मैं अपना जवाब वैसे भी प्रदर्शित करूंगा।

मुझे लगता है कि मैं इसे और अधिक स्वाभाविक मानता हूं, मैंने डोनेलल के उत्तर (डबल-क्लिक को छोड़ दिया) का हिस्सा चुना है । हालांकि, gcores की तरह मैं एक व्युत्पन्न वर्ग बनाने की आवश्यकता को नापसंद करता हूं। लेकिन मुझे भी gcores OnStartupविधि पसंद नहीं है । और मुझे इसकी आवश्यकता "आम तौर पर लेकिन हमेशा नहीं" आधार पर होती है।

मैंने इसे एक संलग्न के रूप में लागू किया है DependencyPropertyताकि मैं local:SelectTextOnFocus.Active = "True"xaml में सेट कर सकूं। मैं इस तरह से सबसे ज्यादा खुश हूं।

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

public class SelectTextOnFocus : DependencyObject
{
    public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached(
        "Active",
        typeof(bool),
        typeof(SelectTextOnFocus),
        new PropertyMetadata(false, ActivePropertyChanged));

    private static void ActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is TextBox)
        {
            TextBox textBox = d as TextBox;
            if ((e.NewValue as bool?).GetValueOrDefault(false))
            {
                textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
            }
            else
            {
                textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
            }
        }
    }

    private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);

        if (dependencyObject == null)
        {
            return;
        }

        var textBox = (TextBox)dependencyObject;
        if (!textBox.IsKeyboardFocusWithin)
        {
            textBox.Focus();
            e.Handled = true;
        }
    }

    private static DependencyObject GetParentFromVisualTree(object source)
    {
        DependencyObject parent = source as UIElement;
        while (parent != null && !(parent is TextBox))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent;
    }

    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
    {
        TextBox textBox = e.OriginalSource as TextBox;
        if (textBox != null)
        {
            textBox.SelectAll();
        }
    }

    [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetActive(DependencyObject @object)
    {
        return (bool) @object.GetValue(ActiveProperty);
    }

    public static void SetActive(DependencyObject @object, bool value)
    {
        @object.SetValue(ActiveProperty, value);
    }
}

मेरे "सामान्य, लेकिन हमेशा नहीं" सुविधा के लिए मैंने यह अटैच प्रॉपर्टी Trueएक (वैश्विक) में सेट की है TextBox Style। इस तरह "टेक्स्ट का चयन करना" हमेशा "चालू" होता है, लेकिन मैं इसे प्रति-टेक्स्टबॉक्स-बेस पर अक्षम कर सकता हूं।


8
+1 यह विश्व स्तर पर स्थापित करने से बहुत बेहतर है, और यह TextBox से प्राप्त होने की तुलना में अधिक 'WPF तरीका' है।
टिजिन

3
+1 stijn से सहमत हैं। App.cs में आपके कोड को "छिपाना" गरीब देव के लिए अच्छा नहीं है, जिन्हें यह पता लगाना है कि SelectAllOnFocus क्यों हो रहा है। :-) मैंने इसे केवल TextBoxBehaviors के लिए अपनी कक्षा में गिरा दिया और फिर अपना आधार TextBox स्टाइल अपडेट किया। एक इलाज का काम किया। चीयर्स
ली कैंपबेल

2
@tronda: केवल टेक्स्टबॉक्स के टारगेट टाइप का उपयोग करके संसाधनों में एक शैली जोड़ें। मेरा सुझाव है कि आप wpftutorial.net/Styles.html
Nils

2
सर्वश्रेष्ठ उत्तर के लिए एक और +1। केवल समस्या मुझे लगती है कि सही माउस बटन का उपयोग करने पर भी पाठ हमेशा चुना जाता है - जो मैं अक्सर संदर्भ मेनू के माध्यम से पाठ को संपादित करने के लिए करता हूं - समाधान इस मामले के लिए काम नहीं करता है क्योंकि यह हमेशा सभी पाठ का चयन करता है, भले ही मैं सिर्फ संदर्भ मेनू के माध्यम से 1 शब्द काटना चाहता था। क्या आप लोग जानते हैं कि इसे कैसे ठीक किया जाए?
user3313608

2
मुझे यह उत्तर पसंद है लेकिन आपको डिपेंडेंसीऑबजेक्ट का विस्तार क्यों करना है? मैंने वह हटा दिया और यह अभी भी ठीक काम करता है।
फ्रेड

47

यहां आपकी सुविधा के लिए उत्तर समाधान को लागू करने वाले ब्लेंड व्यवहार हैं:

एकल टेक्स्टबॉक्स में संलग्न करने के लिए एक:

public class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture += AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture -= AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
    }

    private void AssociatedObjectGotKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        AssociatedObject.SelectAll();
    }

    private void AssociatedObjectGotMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        AssociatedObject.SelectAll();   
    }

    private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if(!AssociatedObject.IsKeyboardFocusWithin)
        {
            AssociatedObject.Focus();
            e.Handled = true;
        }
    }
}

और कई TextBox'es युक्त कंटेनर की जड़ में संलग्न करने के लिए एक:

public class SelectAllTextOnFocusMultiBehavior : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture += HandleMouseCapture;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture -= HandleMouseCapture;
    }

    private static void HandleKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        var txt = e.NewFocus as TextBox;
        if (txt != null)
            txt.SelectAll();
    }

    private static void HandleMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        var txt = e.OriginalSource as TextBox;
        if (txt != null)
            txt.SelectAll();
    }
}

यह अब तक का सबसे अच्छा और साफ समाधान है। इसे साझा करने के लिए बहुत बहुत धन्यवाद।
गोलवेलियस

यह वास्तव में अच्छा लग रहा है, लेकिन किसी कारण से यह टैब नियंत्रण को तोड़ देता है ... किसी भी विचार क्यों?
मार्क

मैं yor समाधान का उपयोग करना चाहूंगा। लेकिन वास्तव में हार गए ... शायद आपके पास एक नमूना है?
जुआन पाब्लो गोमेज़

जब आप ध्यान केंद्रित करते हुए टेक्स्टबॉक्स में कहीं क्लिक करते हैं (कल्पना करें कि आप किसी अन्य स्थान पर कैरेट को स्थानांतरित करना चाहते हैं) तो यह कैरेट को स्थानांतरित करने के बजाय फिर से SelectAll होगा। यह अप्रत्याशित है। GotDouseCapture को MouseDoubleClick के साथ बदलकर इसे ठीक किया है जो कि आम है। MSDN से बाद के समाधान के लिए धन्यवाद।
norekhov

1
जब टेक्स्टबॉक्स FocusManager.FocusedElement के माध्यम से प्रारंभिक फोकस प्राप्त करता है तो यह काम नहीं करता है। कोई विचार क्यों?
5

24

हालांकि यह एक पुराना सवाल है, मुझे अभी यह समस्या थी लेकिन सर्गेई के जवाब में एक्सप्रेशन बिहेवियर के बजाय अटैच्ड बिहेवियर का इस्तेमाल करके इसे हल किया। इसका मतलब है कि मुझे System.Windows.Interactivityब्लेंड एसडीके पर निर्भरता की आवश्यकता नहीं है :

public class TextBoxBehavior
{
    public static bool GetSelectAllTextOnFocus(TextBox textBox)
    {
        return (bool)textBox.GetValue(SelectAllTextOnFocusProperty);
    }

    public static void SetSelectAllTextOnFocus(TextBox textBox, bool value)
    {
        textBox.SetValue(SelectAllTextOnFocusProperty, value);
    }

    public static readonly DependencyProperty SelectAllTextOnFocusProperty =
        DependencyProperty.RegisterAttached(
            "SelectAllTextOnFocus",
            typeof (bool),
            typeof (TextBoxBehavior),
            new UIPropertyMetadata(false, OnSelectAllTextOnFocusChanged));

    private static void OnSelectAllTextOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBox = d as TextBox;
        if (textBox == null) return;

        if (e.NewValue is bool == false) return;

        if ((bool) e.NewValue)
        {
            textBox.GotFocus += SelectAll;
            textBox.PreviewMouseDown += IgnoreMouseButton;
        }
        else
        {
            textBox.GotFocus -= SelectAll;
            textBox.PreviewMouseDown -= IgnoreMouseButton;
        }
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox == null) return;
        textBox.SelectAll();
    }

    private static void IgnoreMouseButton(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null || (!textBox.IsReadOnly && textBox.IsKeyboardFocusWithin)) return;

        e.Handled = true;
        textBox.Focus();
    }
}

आप इसे अपने XAML में इस तरह से उपयोग कर सकते हैं:

<TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>

मैंने इसके बारे में यहां ब्लॉग किया है


मुझे यह तरीका पसंद है लेकिन गेट / सेट के तरीके "संपत्ति" में समाप्त नहीं होने चाहिए; मुझे यह हटाना पड़ा कि Xaml भाग को जोड़ने के बाद कोड संकलन करने के लिए।
पैट्रिक क्वर्क

बहुत अच्छा, उम्मीद के मुताबिक काम किया। मुझे यह पसंद है क्योंकि यह मुझे MVVM करते समय व्यू चिंताओं को अलग रखने में मदद करता है।
किलनीन

16

यहाँ MSDN पर एक बहुत अच्छा बहुत सरल उपाय है :

<TextBox
    MouseDoubleClick="SelectAddress"
    GotKeyboardFocus="SelectAddress"
    PreviewMouseLeftButtonDown="SelectivelyIgnoreMouseButton" />

यहाँ पीछे कोड है:

private void SelectAddress(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        tb.SelectAll();
    }
}

private void SelectivelyIgnoreMouseButton(object sender,
    MouseButtonEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        if (!tb.IsKeyboardFocusWithin)
        {
            e.Handled = true;
            tb.Focus();
        }
    }
}

1
अनिवार्य रूप से, यह वही समाधान है जो इस धागे में सबसे अधिक रेटेड है। लेकिन चूंकि यह दो साल पहले था, अब मुझे पता है कि @ डोनलेल ने इसे कहां से उधार लिया है?)
सर्गेई एल्डुखोव

यह समाधान सबसे आसान लग रहा था और मेरे लिए काम कर रहा था। मैं टेक्स्ट बॉक्स में प्रवेश करते समय डिफ़ॉल्ट रूप से चयनित पाठ का एक विशिष्ट सबसेट चाहता था।
जैक बी निंबले

10

मुझे लगता है कि यह अच्छी तरह से काम करता है:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (TextBox)e.OriginalSource;
    tb.Dispatcher.BeginInvoke(
        new Action(delegate
            {
                tb.SelectAll();
            }), System.Windows.Threading.DispatcherPriority.Input);
}

यदि आप इसे विस्तार विधि के रूप में लागू करना चाहते हैं:

public static void SelectAllText(this System.Windows.Controls.TextBox tb)
{
    tb.Dispatcher.BeginInvoke(
        new Action(delegate
        {
            tb.SelectAll();
        }), System.Windows.Threading.DispatcherPriority.Input);
}

और आपके GotFocusकार्यक्रम में:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (TextBox)e.OriginalSource;
    tb.SelectAllText();
}

मैंने ऊपर दिए गए समाधान की खोज की क्योंकि कई महीने पहले मैं किसी दिए गए फ़ोकस को सेट करने का तरीका ढूंढ रहा था UIElement। मैंने कहीं नीचे कोड की खोज की (क्रेडिट इसके द्वारा दिया गया है) और यह अच्छी तरह से काम करता है। मैं इसे पोस्ट करता हूं, हालांकि यह सीधे ओपी के सवाल से संबंधित नहीं है क्योंकि यह Dispatcherए के साथ काम करने के लिए उपयोग करने के समान पैटर्न को दर्शाता है UIElement

// Sets focus to uiElement
public static void DelayedFocus(this UIElement uiElement)
{
    uiElement.Dispatcher.BeginInvoke(
    new Action(delegate
    {
        uiElement.Focusable = true;
        uiElement.Focus();
        Keyboard.Focus(uiElement);
    }),
    DispatcherPriority.Render);
}

मुझे लगता है कि इसे लागू करने का सबसे सरल तरीका है। एक्सटेंशन विधि बनाने के बाद आपको बस myTextBox.SelectAllText () को कॉल करना होगा। इस उत्तर को अधिक अंक क्यों नहीं मिले हैं? अन्य समाधान इतने बेहतर क्यों हैं?
टोनो नाम

2
मैं इस पद्धति से बचना चाहूंगा क्योंकि यह टेक्स्टबॉक्स के माउसअप हैंडलर के बाद चलने के लिए एक async कॉल पर निर्भर है। मुझे विश्वास नहीं है कि यह 100% नियतात्मक होगा, और असंगत व्यवहार हो सकता है। भले ही यह होने की संभावना न हो, लेकिन मैं ऊपर दिए गए अचूक तरीकों के साथ जाना चाहूंगा।
रॉब एच

6

यहाँ कुछ समस्याओं को अन्य समाधानों के साथ हल करने का प्रयास किया गया है:

  1. कट / कॉपी / पास्ट के लिए राइट क्लिक के संदर्भ मेनू का उपयोग करना सभी पाठ का चयन करता है, भले ही आपने यह सब नहीं चुना हो।
  2. राइट क्लिक संदर्भ मेनू से लौटते समय, सभी पाठ हमेशा चुने जाते हैं।
  3. Alt+ के साथ आवेदन पर लौटते समय Tab, सभी पाठ हमेशा चुने जाते हैं।
  4. जब पहली क्लिक पर पाठ के केवल भाग का चयन करने का प्रयास किया जाता है, तो सभी को हमेशा चुना जाता है (उदाहरण के लिए Google क्रोमस एड्रेस बार के विपरीत)।

मेरे द्वारा लिखा गया कोड विन्यास योग्य है। आप क्या कार्रवाई सब व्यवहार का चयन तीन केवल पढ़ने के लिए क्षेत्रों की स्थापना द्वारा होने चाहिए पर चुन सकते हैं: SelectOnKeybourdFocus, SelectOnMouseLeftClick, SelectOnMouseRightClick

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

public static class TextBoxExtensions
{
    // Configuration fields to choose on what actions the select all behavior should occur.
    static readonly bool SelectOnKeybourdFocus = true;
    static readonly bool SelectOnMouseLeftClick = true;
    static readonly bool SelectOnMouseRightClick = true;

    // Remembers a right click context menu that is opened 
    static ContextMenu ContextMenu = null;

    // Remembers if the first action on the TextBox is mouse down 
    static bool FirstActionIsMouseDown = false;

    public static readonly DependencyProperty SelectOnFocusProperty =
        DependencyProperty.RegisterAttached("SelectOnFocus", typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false, new PropertyChangedCallback(OnSelectOnFocusChanged)));

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetSelectOnFocus(DependencyObject obj)
    {
        return (bool)obj.GetValue(SelectOnFocusProperty);
    }

    public static void SetSelectOnFocus(DependencyObject obj, bool value)
    {
        obj.SetValue(SelectOnFocusProperty, value);
    }

    private static void OnSelectOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is TextBox textBox)) return;

        if (GetSelectOnFocus(textBox))
        {
            // Register events
            textBox.PreviewMouseDown += TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp += TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus += TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus += TextBox_LostKeyboardFocus;
        }
        else
        {
            // Unregister events
            textBox.PreviewMouseDown -= TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp -= TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus -= TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus -= TextBox_LostKeyboardFocus;
        }
    }

    private static void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // If mouse clicked and focus was not in text box, remember this is the first click.
        // This will enable to prevent select all when the text box gets the keyboard focus 
        // right after the mouse down event.
        if (!textBox.IsKeyboardFocusWithin)
        {
            FirstActionIsMouseDown = true;
        }
    }

    private static void TextBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnMouseLeftClick/SelectOnMouseRightClick is true and left/right button was clicked
        // 3) This is the first click
        // 4) No text is selected
        if (((SelectOnMouseLeftClick && e.ChangedButton == MouseButton.Left) || 
            (SelectOnMouseRightClick && e.ChangedButton == MouseButton.Right)) &&
            FirstActionIsMouseDown &&
            string.IsNullOrEmpty(textBox.SelectedText))
        {
            textBox.SelectAll();
        }

        // It is not the first click 
        FirstActionIsMouseDown = false;
    }

    private static void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnKeybourdFocus is true
        // 2) Focus was not previously out of the application (e.OldFocus != null)
        // 3) The mouse was pressed down for the first after on the text box
        // 4) Focus was not previously in the context menu
        if (SelectOnKeybourdFocus &&
            e.OldFocus != null &&
            !FirstActionIsMouseDown &&
            !IsObjectInObjectTree(e.OldFocus as DependencyObject, ContextMenu))
        {
            textBox.SelectAll();
        }

        // Forget ContextMenu
        ContextMenu = null;
    }

    private static void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Remember ContextMenu (if opened)
        ContextMenu = e.NewFocus as ContextMenu;

        // Forget selection when focus is lost if:
        // 1) Focus is still in the application
        // 2) The context menu was not opened
        if (e.NewFocus != null
            && ContextMenu == null)
        {
            textBox.SelectionLength = 0;
        }
    }

    // Helper function to look if a DependencyObject is contained in the visual tree of another object
    private static bool IsObjectInObjectTree(DependencyObject searchInObject, DependencyObject compireToObject)
    {
        while (searchInObject != null && searchInObject != compireToObject)
        {
            searchInObject = VisualTreeHelper.GetParent(searchInObject);
        }

        return searchInObject != null;
    }
}

अटैच्ड प्रॉपर्टी को अटेच करने के लिए TextBox, आपको केवल प्रॉपर्टी की एक्सएमएल नेमस्पेस ( xmlns) जोड़ना है और फिर इसे इस तरह इस्तेमाल करना है:

<TextBox attachedprop:TextBoxExtensions.SelectOnFocus="True"/>

इस समाधान के बारे में कुछ नोट्स:

  1. माउस डाउन ईवेंट के डिफ़ॉल्ट व्यवहार को ओवरराइड करने के लिए और पहले क्लिक पर टेक्स्ट के केवल भाग का चयन करने में सक्षम करने के लिए, सभी टेक्स्ट को माउस अप इवेंट पर चुना जाता है।
  2. मुझे इस तथ्य से निपटना था कि TextBoxध्यान खो देने के बाद इसका चयन याद रहता है। मैंने वास्तव में इस व्यवहार को ओवरराइड किया है।
  3. मुझे याद रखना चाहिए कि क्या एक माउस बटन नीचे TextBox( FirstActionIsMouseDownस्थिर क्षेत्र) पर पहली क्रिया है ।
  4. मुझे राइट क्लिक ( ContextMenuस्टैटिक फील्ड) द्वारा खोला गया संदर्भ मेनू याद रखना था ।

एकमात्र दुष्प्रभाव जो मुझे मिला SelectOnMouseRightClickवह सच है। कभी-कभी राइट-क्लिक संदर्भ मेनू फ़्लिकर होता है, जब इसके खुले और एक रिक्त पर राइट-क्लिक TextBoxकरने से "सभी का चयन करें" नहीं होता है।


5

मैंने पाया है कि यहां प्रस्तुत कोई भी उत्तर मानक विंडोज टेक्स्टबॉक्स की नकल नहीं करता है। उदाहरण के लिए, टेक्स्टबॉक्स के अंतिम वर्ण और टेक्स्टबॉक्स के दाईं ओर के बीच सफेद स्थान पर क्लिक करने का प्रयास करें। यहां अधिकांश समाधान हमेशा संपूर्ण सामग्री का चयन करेंगे, जिससे पाठ को टेक्स्टबॉक्स में जोड़ना बहुत मुश्किल हो जाता है।

मैं यहां जो उत्तर प्रस्तुत करता हूं वह इस संबंध में बेहतर व्यवहार करता है। यह एक व्यवहार है (इसलिए इसके लिए System.Windows की आवश्यकता है । Blend SDK से निष्क्रियता विधानसभा )। संलग्न गुणों का उपयोग करके इसे फिर से लिखा जा सकता है।

public sealed class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
    }

    void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // Find the textbox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        var textBox = parent as TextBox;
        Debug.Assert(textBox != null);

        if (textBox.IsFocused) return;

        textBox.SelectAll();
        Keyboard.Focus(textBox);
        e.Handled = true;
    }
}

यह उस कोड पर आधारित है जो मैंने यहां पाया है


1
हालांकि यह एक अच्छा जवाब है, मुझे लगता है कि जब उपयोगकर्ता श्वेत स्थान पर क्लिक करता है तो उसका इरादा (किसी व्यावसायिक अनुप्रयोग में) संभवत: पूरे मूल्य को ओवरराइड करना है, इसलिए सभी का चयन करना सही दृष्टिकोण है।
सर्गेई Aldoukhov

1
सर्गेई: पहला क्लिक पूरे मूल्य का चयन करेगा, दूसरा क्लिक मूल्य के दाईं ओर कर्सर रखेगा। अन्य प्रस्तुत समाधानों में, दूसरा क्लिक पूरे मूल्य को चयनित रखेगा, जिससे मूल्य को जोड़ना बहुत मुश्किल हो जाएगा।
क्रिस्टोफ़ वर्बिएस्ट

इसका उपयोग कैसे किया जाता है? मैंने इस कोड को App.xaml.cs में जोड़ा, लेकिन मेरे ऐप में टेक्स्टबॉक्स पर इसका कोई असर नहीं हुआ।
पंतग डेग

5

यह सरल कार्यान्वयन मेरे लिए पूरी तरह से काम करता है:

void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    ((TextBox) sender).SelectAll();
}

void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var TextBox = (TextBox) sender;
    if (!TextBox.IsKeyboardFocusWithin)
    {
        TextBox.Focus();
        e.Handled = true;
    }
}

इसे सभी पर लागू करने के लिए TextBox, निम्नलिखित कोड डालेंInitializeComponent();

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));

4

App.xaml फ़ाइल में:

<Application.Resources>
    <Style TargetType="TextBox">
        <EventSetter Event="GotKeyboardFocus" Handler="TextBox_GotKeyboardFocus"/>
    </Style>
</Application.Resources>

App.xaml.cs फ़ाइल में:

private void TextBox_GotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
{
    ((TextBox)sender).SelectAll();
}

इस कोड के साथ आप TextBoxअपने आवेदन में सभी तक पहुँचते हैं ।


3

यहाँ से लिया गया :

App.xaml.cs फ़ाइल में वैश्विक ईवेंट हैंडलर पंजीकृत करें:

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),TextBox.GotFocusEvent,
    new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

फिर हैंडलर उतना ही सरल है:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

3

मुझे लगता है कि यह बहुत पुराना है, लेकिन यहां मेरा समाधान है जो अभिव्यक्तियों / Microsoft अन्तरक्रियाशीलता और इंटरैक्शन नाम रिक्त स्थान पर आधारित है।

सबसे पहले, मैंने इस लिंक के निर्देशों का अनुसरण करते हुए अन्तरक्रियाशीलता को एक शैली में ट्रिगर किया।

फिर यह नीचे आता है

<Style x:Key="baseTextBox" TargetType="TextBox">
  <Setter Property="gint:InteractivityItems.Template">
    <Setter.Value>
      <gint:InteractivityTemplate>
        <gint:InteractivityItems>
          <gint:InteractivityItems.Triggers>
            <i:EventTrigger EventName="GotKeyboardFocus">
              <ei:CallMethodAction MethodName="SelectAll"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
              <ei:CallMethodAction MethodName="TextBox_PreviewMouseLeftButtonDown"
                TargetObject="{Binding ElementName=HostElementName}"/>
            </i:EventTrigger>
          </gint:InteractivityItems.Triggers>
        </gint:InteractivityItems>
      </gint:InteractivityTemplate>
    </Setter.Value>
  </Setter>
</Style>

और इस

public void TextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
  TextBox tb = e.Source as TextBox;
  if((tb != null) && (tb.IsKeyboardFocusWithin == false))
  {
    tb.Focus();
    e.Handled = true;
  }
}

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

आग लगने पर घटना होने पर सबसे पहले CallMethodActionटेक्स्ट बॉक्स का SelectAllतरीका कहता है ।GotKeyboardFocusTextBox

आशा है कि ये आपकी मदद करेगा।


चूँकि यह इतना पुराना प्रश्न है, यह आपके उत्तर को कुछ ध्यान देने में मदद कर सकता है यदि आप उल्लेख करते हैं कि कोई व्यक्ति इस दृष्टिकोण को क्यों चुन सकता है।
विभिषण

सबसे पहले, इसे एक शैली में डालने की आवश्यकता नहीं है, लेकिन मुझे लगता है कि यह स्पष्ट है कि कई पाठ बॉक्स नियंत्रण हैं जिन्हें इसकी आवश्यकता है, एक शैली जाने का रास्ता है।
वियोजया

1
हो सकता है कि कुछ इस दृष्टिकोण से सहमत नहीं होंगे, हालांकि, जैसा कि आप इस दृष्टिकोण का उपयोग क्यों कर सकते हैं, इसके लिए उप-पाठ टेक्स्टबॉक्स की आवश्यकता नहीं है, क्लास हैंडलर घटनाओं को दर्ज करना, विस्तार विधियों, संलग्न गुण बनाना, आदि। एक शैली के रूप में, इसे भी जोड़ा जा सकता है। किसी भी xaml परियोजना के संसाधन शब्दकोश। एक्स के बिना: कुंजी, यह प्रत्येक व्यक्ति पाठ बॉक्स के xaml को बदलने के बिना संसाधन शब्दकोश के दायरे में किसी भी टेक्स्टबॉक्स उदाहरण पर लागू किया जाएगा। कुछ मामलों में, यह एक क्लीनर दृष्टिकोण हो सकता है।
वियोजया

2

मैंने निल्स के उत्तर का उपयोग किया है लेकिन अधिक लचीले में परिवर्तित किया है।

public enum SelectAllMode
{

    /// <summary>
    ///  On first focus, it selects all then leave off textbox and doesn't check again
    /// </summary>
    OnFirstFocusThenLeaveOff = 0,

    /// <summary>
    ///  On first focus, it selects all then never selects
    /// </summary>
    OnFirstFocusThenNever = 1,

    /// <summary>
    /// Selects all on every focus
    /// </summary>
    OnEveryFocus = 2,

    /// <summary>
    /// Never selects text (WPF's default attitude)
    /// </summary>
    Never = 4,
}

public partial class TextBox : DependencyObject
{
    public static readonly DependencyProperty SelectAllModeProperty = DependencyProperty.RegisterAttached(
        "SelectAllMode",
        typeof(SelectAllMode?),
        typeof(TextBox),
        new PropertyMetadata(SelectAllModePropertyChanged));

    private static void SelectAllModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is System.Windows.Controls.TextBox)
        {
            var textBox = d as System.Windows.Controls.TextBox;

            if (e.NewValue != null)
            {
                textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
            }
            else
            {
                textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
            }
        }
    }

    private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);

        if (dependencyObject == null)
            return;

        var textBox = (System.Windows.Controls.TextBox)dependencyObject;
        if (!textBox.IsKeyboardFocusWithin)
        {
            textBox.Focus();
            e.Handled = true;
        }
    }

    private static DependencyObject GetParentFromVisualTree(object source)
    {
        DependencyObject parent = source as UIElement;
        while (parent != null && !(parent is System.Windows.Controls.TextBox))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent;
    }

    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
    {
        var textBox = e.OriginalSource as System.Windows.Controls.TextBox;
        if (textBox == null) return;

        var selectAllMode = GetSelectAllMode(textBox);

        if (selectAllMode == SelectAllMode.Never)
        {
            textBox.SelectionStart = 0;
            textBox.SelectionLength = 0;
        }
        else
            textBox.SelectAll();

        if (selectAllMode == SelectAllMode.OnFirstFocusThenNever)
            SetSelectAllMode(textBox, SelectAllMode.Never);
        else if (selectAllMode == SelectAllMode.OnFirstFocusThenLeaveOff)
            SetSelectAllMode(textBox, null);
    }

    [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(System.Windows.Controls.TextBox))]
    public static SelectAllMode? GetSelectAllMode(DependencyObject @object)
    {
        return (SelectAllMode)@object.GetValue(SelectAllModeProperty);
    }

    public static void SetSelectAllMode(DependencyObject @object, SelectAllMode? value)
    {
        @object.SetValue(SelectAllModeProperty, value);
    }
}

XAML में, आप इनमें से एक की तरह उपयोग कर सकते हैं:

<!-- On first focus, it selects all then leave off textbox and doesn't check again -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenLeaveOff" />

<!-- On first focus, it selects all then never selects -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenNever" />

<!-- Selects all on every focus -->
<TextBox attprop:TextBox.SelectAllMode="OnEveryFocus" />

<!-- Never selects text (WPF's default attitude) -->
<TextBox attprop:TextBox.SelectAllMode="Never" />

1
टेम्प्लेट में उपयोग के लिए वास्तव में अच्छा समाधान है क्योंकि आप इसे किसी वास्तविक कोडबेहैंड के बिना xaml में बाँध सकते हैं, बस टेक्स्टबॉक्स का विस्तारित व्यवहार।
एरिक जोहानसन

2

यहां @Nasenbaer द्वारा पोस्ट किए गए उत्तर का C # संस्करण है

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}

जहाँ तक MyTextBox_GotFocus ईवेंट हैंडलर को GotFocusईवेंट के लिए असाइन किया गया है MyTextBox


2

मेरे पास इसके लिए थोड़ा सरलीकृत उत्तर है (सिर्फ के साथ) PreviewMouseLeftButtonDown घटना के साथ) जो ब्राउज़र की सामान्य कार्यक्षमता की नकल करता है:

XAML में आपका TextBoxकहना है:

<TextBox Text="http://www.blabla.com" BorderThickness="2" BorderBrush="Green" VerticalAlignment="Center" Height="25"
                 PreviewMouseLeftButtonDown="SelectAll" />

कोडबेहिंद में:

private void SelectAll(object sender, MouseButtonEventArgs e)
{
    TextBox tb = (sender as TextBox);

    if (tb == null)
    {
        return;
    }

    if (!tb.IsKeyboardFocusWithin)
    {
        tb.SelectAll();
        e.Handled = true;
        tb.Focus();
    }
}

1
जो लोग अपने आवेदन के आसपास अपना रास्ता टैब के लिए अंदर TextBox.SelectAll () के साथ एक GotKeyboardFocus घटना जोड़ना चाहते हो सकता है। आपका समाधान पासवर्डबॉक्स के लिए भी काम करता है (चूंकि पासवर्डबॉक्स सील किए गए प्रकार हैं जिन्हें वे बढ़ाया नहीं जा सकता है)।
डेविड शेरेट

1

किसी भी TextBox नियंत्रण में वांछित व्यवहार जोड़ने के लिए इस विस्तार विधि का प्रयास करें। मैंने इसे अभी तक बड़े पैमाने पर परीक्षण नहीं किया है, लेकिन यह मेरी जरूरतों को पूरा करता है।

public static class TextBoxExtensions
{
    public static void SetupSelectAllOnGotFocus(this TextBox source)
    {
        source.GotFocus += SelectAll;
        source.PreviewMouseLeftButtonDown += SelectivelyIgnoreMouseButton;
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }

    private static void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {
            if (!textBox.IsKeyboardFocusWithin)
            {
                e.Handled = true;
                textBox.Focus();
            }
        }
    }
}

1

मैंने समाधान के लिए बहुत खोज की, मुझे चयन के लिए कुछ समाधान मिले, लेकिन, यह मुद्दा तब है जब हम टेक्स्ट बॉक्स से टेक्स्ट के भाग का चयन करने के बाद राइट क्लिक करते हैं और कट / कॉपी करते हैं, यह सभी का चयन करता है यहां तक ​​कि मैंने टेक्स्ट के चयनित भाग को भी चुना है। इसे ठीक करने के लिए यहां समाधान है। कीबोर्ड सेलेक्ट इवेंट में बस नीचे दिए गए कोड को जोड़ें। इसने मेरे लिए काम किया।

private static void SelectContentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is TextBox)
    {
        TextBox textBox = d as TextBox;
        if ((e.NewValue as bool?).GetValueOrDefault(false))
        {
            textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;                 
        }
        else
        {
            textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;

        }
    }
}


private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
{
    if (e.KeyboardDevice.IsKeyDown(Key.Tab))
        ((TextBox)sender).SelectAll();
}

1

मुझे भी यही समस्या थी। VB.Net में यह इस तरह आसान काम करता है:

VB XAML:

<TextBox x:Name="txtFilterFrequency" />

Codehind:

Private Sub txtFilterText_GotFocus(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles txtFilterText.GotFocus
    Me.Dispatcher.BeginInvoke(Sub()
                                  txtFilterText.SelectAll()
                              End Sub, DispatcherPriority.ApplicationIdle, Nothing)
End Sub

सी # (ViRuSTriNiTy के लिए धन्यवाद)

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}

मेरे लिए सबसे अच्छा समाधान, मैंने यहाँ एक सी # अनुवाद पोस्ट किया है: stackoverflow.com/a/48385409/3936440
ViRuSTriNiTy

मेरे लिए, यह दृष्टिकोण कभी-कभी पाठ का चयन करने में विफल रहता है। मुझे लगता है कि BeginInvoke के कारण यह दौड़ की स्थिति है।
Vimes

कृपया निर्दिष्ट करें। डिस्पैचर प्राथमिकता अपेक्षा के अनुसार डिफ़ॉल्ट अनुप्रयोगों पर काम कर रही है। आपकी क्या स्थिति है? क्या आपने वर्णित के रूप में सटीक प्रयास किया? आपके समाधान में कुछ खास?
नसनबेर

1

यह अब तक का सबसे सरल उपाय है।

एप्लिकेशन (App.xaml.cs) और किया गया एक वैश्विक हैंडलर जोड़ें। आपको कोड की केवल कुछ पंक्तियों की आवश्यकता होगी।

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.GotFocusEvent,
        new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

तो एक प्रकार (TextBox) के खिलाफ वैश्विक इवेंट हैंडलर को पंजीकृत करने के लिए EventManager वर्ग का उपयोग करें। वास्तविक हैंडलर मृत सरल है:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

यहा जांचिये: फोकस पर WPF टेक्स्टबॉक्स SelectAll

आशा करता हूँ की ये काम करेगा।


1

डोनली / ग्रोकी के दृष्टिकोण में दिलचस्पी रखने वालों के लिए, लेकिन TextBoxदर्ज किए गए पाठ के अंत में कैरेट लगाने के लिए अंतिम वर्ण के दाईं ओर (लेकिन अभी भी ) एक क्लिक करना चाहते हैं , मैं इस समाधान के साथ आया हूं:

int GetRoundedCharacterIndexFromPoint(TextBox textBox, Point clickedPoint)
{
    int position = textBox.GetCharacterIndexFromPoint(clickedPoint, true);

    // Check if the clicked point is actually closer to the next character
    // or if it exceeds the righmost character in the textbox
    // (in this case return increase the position by 1)
    Rect charLeftEdge = textBox.GetRectFromCharacterIndex(position, false);
    Rect charRightEdge = textBox.GetRectFromCharacterIndex(position, true);
    double charWidth = charRightEdge.X - charLeftEdge.X;
    if (clickedPoint.X + charWidth / 2 > charLeftEdge.X + charWidth) position++;

    return position;
}

void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
{
    // Find the TextBox
    DependencyObject parent = e.OriginalSource as UIElement;
    while (parent != null && !(parent is TextBox))
        parent = VisualTreeHelper.GetParent(parent);

    if (parent != null)
    {
        var textBox = (TextBox)parent;
        if (!textBox.IsKeyboardFocusWithin)
        {
            // If the text box is not yet focused, give it the focus and
            // stop further processing of this click event.
            textBox.Focus();
            e.Handled = true;
        }
        else
        {
            int pos = GetRoundedCharacterIndexFromPoint(textBox, e.GetPosition(textBox));
            textBox.CaretIndex = pos;
        }
    }
}

void SelectAllText(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        textBox.SelectAll();
}

GetRoundedCharacterIndexFromPointविधि से लिया गया है इस पोस्ट।


1
ठीक काम करता है, लेकिन डबल क्लिक इवेंट ट्रिगर नहीं होता है
रोड्रिगो कैबलेरो

वास्तव में यह डबलक्लिक इवेंट में प्रवेश करता है लेकिन ओरिजनल सोर्स प्रॉपर्टी टेक्स्टबॉक्स व्यू का प्रकार है। तो SelectAllText विधि इस तरह होनी चाहिए: निजी स्थिर शून्य SelectAllText (ऑब्जेक्ट प्रेषक, RoutedEventArgs e) {var textBox = e.OriginalSource TextBox के रूप में; if (textBox! = null) {textBox.SelectAll (); System.Diagnostics.Debug.WriteLine ("चयनित सभी"); } और अगर (प्रेषक TextBox है) {(TextBox के रूप में प्रेषक) .SelectAll (); }
रोड्रिगो कैबेलेरो

1

गुग्लिंग और परीक्षण के बाद, मुझे एक सरल समाधान मिला है जो मेरे लिए काम करता है।

आपको Loadedअपने कंटेनर विंडो की ईवेंट हैंडलर जोड़ने की आवश्यकता है :

private void yourwindow_Loaded(object sender, RoutedEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.PreviewMouseLeftButtonDownEvent,
        new RoutedEventHandler(SelectivelyIgnoreMouseButton));
}

अगला, आपको RoutedEventHandlerपिछले कोड में संदर्भित हैंडलर बनाना है :

private void SelectivelyIgnoreMouseButton(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        if (!tb.IsKeyboardFocusWithin)
        {
            e.Handled = true;
            tb.Focus();
        }
    }
}

अब, आप अलग से किसी भी नियंत्रण के लिए ईवेंट हैंडलर SelectAll()पर कमांड जोड़ सकते हैं :GotFocusTextBox

private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

आपका पाठ अब फ़ोकस पर चयनित है!

डॉ। WPF समाधान, MSDN मंच से अनुकूलित


मैंने अभी उपयोग किया है: निजी async void TBTime_GotFocus (ऑब्जेक्ट प्रेषक, RoutedEventArgs e) {TextBox tb = (TextBox) e.OriginalSource; Dispatcher.RunAsync (Windows.UI.Core.CoreDispatcherPyerity.Normal, async () => {tb.SelectAll ();}); }
डेविड जोन्स

1
#region TextBoxIDCard selection
private bool textBoxIDCardGotFocus = false;
private void TextBoxIDCard_GotFocus(object sender, RoutedEventArgs e)
{
    this.TextBoxIDCard.SelectAll();
}

private void TextBoxIDCard_LostFocus(object sender, RoutedEventArgs e)
{
    textBoxIDCardGotFocus = false;
}

private void TextBoxIDCard_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (textBoxIDCardGotFocus == false)
    {
        e.Handled = true;
        this.TextBoxIDCard.Focus();
        textBoxIDCardGotFocus = true;
    }
} 
#endregion

यदि आपके पास एक विंडो पर 20 टेक्स्टबॉक्स हैं, तो क्या आप हर टेक्स्टबॉक्स के लिए 3 तरीके बनाएंगे? यह दृष्टिकोण अच्छा नहीं है। यहां देखें: rachel53461.wordpress.com/2011/11/05/…
अलेक्जेंड्रू डिकु

0

यह मेरे लिए अच्छा काम करता है। यह मूल रूप से कुछ पहले के पदों का पुनरावर्तन है। मैंने अभी इसे अपने MainWindow.xaml.cs फ़ाइल को कंस्ट्रक्टर में डाला है। मैं दो हैंडलर बनाता हूं, एक कीबोर्ड के लिए, और एक माउस के लिए, और एक ही फ़ंक्शन में दोनों घटनाओं को फ़नल करता है HandleGotFocusEvent, जो कि एक ही फाइल में कंस्ट्रक्टर के ठीक बाद परिभाषित किया गया है।

public MainWindow()
{
   InitializeComponent();

   EventManager.RegisterClassHandler(typeof(TextBox), 
      UIElement.GotKeyboardFocusEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);
   EventManager.RegisterClassHandler(typeof(TextBox),
      UIElement.GotMouseCaptureEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);   
}
private void HandleGotFocusEvent(object sender, RoutedEventArgs e)
{
   if (sender is TextBox)
      (sender as TextBox).SelectAll();
}

अच्छा और आसान है, लेकिन लगता है कि समय की समस्या है - हर दूसरे प्रयास (माउस क्लिक), यह तुरंत फिर से चयन करता है ...?
T4NK3R

0

माउसडाउन को ओवरराइड करने का एक आसान तरीका और डबलक्लिक के बाद सभी का चयन करना है:

public class DoubleClickTextBox: TextBox
{

    public override void EndInit()
    {
        base.EndInit();            
    }

    protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
    {
        base.OnMouseEnter(e);
        this.Cursor = Cursors.Arrow;
    }
    protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
    {

    }

    protected override void OnMouseDoubleClick(System.Windows.Input.MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        this.SelectAll();
    }
}

0

अपने टेक्स्टबॉक्स को नियंत्रित करने वाले जो कुछ भी हो, उसके निर्माण में डालने की कोशिश करें:

Loaded += (sender, e) =>
{
    MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    myTextBox.SelectAll();
}

जब आप इसे विंडो कंस्ट्रक्टर में रखते हैं तो यह दृष्टिकोण काम नहीं करता है।
विरूस्तृतीय

0

यदि कोई ऐसी घटना है जो OnFocusमाउस के दौरान पाठ को रद्द कर देती है, तो मैं आमतौर पर सभी का चयन करने में देरी करता हूं।

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (TextBox.Text != null)
    {
        _ = Task.Run(() =>
        {
            Dispatcher.Invoke(
                async () => {
                    await Task.Delay(100);
                    TextBox.SelectAll();
                }
            );
        });
    }
}

-1

मैंने उन सभी का परीक्षण किया है लेकिन केवल निम्नलिखित ने काम किया है:

protected override void OnStartup(StartupEventArgs e) 
{
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent,
   new MouseButtonEventHandler(SelectivelyHandleMouseButton), true);
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotKeyboardFocusEvent,
      new RoutedEventHandler(SelectAllText), true);
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
      new RoutedEventHandler(GotFocus), true);          
}

private static void SelectivelyHandleMouseButton(object sender, MouseButtonEventArgs e)
{
    var textbox = (sender as TextBox);
    if (textbox != null)
    {
        int hc = textbox.GetHashCode();
        if (hc == LastHashCode)
        {
            if (e.OriginalSource.GetType().Name == "TextBoxView")
            {
                e.Handled = true;
                textbox.Focus();
                LastHashCode = -1;
            }
        }
    }
    if (textbox != null) textbox.Focus();
}

private static void SelectAllText(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        textBox.SelectAll();
}

private static int LastHashCode;
private static void GotFocus(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        LastHashCode = textBox.GetHashCode();
}

4
यह भी हैश कोड का एक अश्लील दुरुपयोग है। मैं इसे
पढ़ूंगा

3
और का उपयोग कर GetType().Nameके बजाय isया asसुंदर hacky है
RichK

-1

मैं देख रहा हूं कि उत्तर बहुत हैं, लेकिन स्वीकृत के रूप में, जिन विधियों का उपयोग किया जाना चाहिए, वह है EditTextBoxGotCapture

निम्नलिखित कोड के साथ:

private void EditTextBoxGotCapture(object sender, MouseEventArgs e)
{
    if (sender is TextBox tb)
    {
        tb.Select(0, tb.Text.Length);
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.