[.net] جعل WinBorms TextBox تتصرف مثل شريط عنوان المستعرض الخاص بك



14 Answers

لقد وجدت حلا أبسط لهذا. وهو يتضمن إطلاق SelectAll بشكل غير متزامن باستخدام Control.BeginInvoke بحيث يحدث بعد حدوث أحداث Enter و Click:

في C #:

private void MyTextBox_Enter(object sender, EventArgs e)
{
    // Kick off SelectAll asyncronously so that it occurs after Click
    BeginInvoke((Action)delegate
    {
        MyTextBox.SelectAll();
    });
}

في VB.NET (بفضل Krishanu Dey )

Private Sub MyTextBox_Enter(sender As Object, e As EventArgs) Handles MyTextBox.Enter 
    BeginInvoke(DirectCast(Sub() MyTextBox.SelectAll(), Action)) 
End Sub
Question

عندما يتلقى مربع نص C # WinForms التركيز ، أريده أن يتصرف مثل شريط عناوين المتصفح.

لمعرفة ما أعنيه ، انقر في شريط عنوان متصفح الويب الخاص بك. ستلاحظ السلوك التالي:

  1. يجب أن يؤدي النقر في مربع النص إلى تحديد النص بالكامل إذا لم يكن مربع النص قد تم تركيزه مسبقًا.
  2. يجب أن يحدد الماوس لأسفل والسحب في مربع النص فقط النص الذي قمت بتحديده بالماوس.
  3. إذا كان مربع النص يركز بالفعل ، فإن النقر لا يحدد كل النص.
  4. التركيز على مربع النص برمجيا أو عن طريق لوحة المفاتيح tabbing يجب أن يحدد كل النص.

أريد أن أفعل هذا بالضبط في WinForms.

أسرع هجوم ALERT: يرجى قراءة ما يلي قبل الإجابة! شكرا يا شباب. :-)

لا يعمل الاتصال .SelectAll () أثناء أحداث .Enter أو .GotFocus لأنه إذا قام المستخدم بالنقر فوق مربع النص ، فسيتم وضع علامة الإقحام حيث يقوم بالنقر فوقها ، وبالتالي إلغاء تحديد كل النص.

لن يعمل الاتصال .SelectAll () أثناء حدث .Click نظرًا لأن المستخدم لن يتمكن من تحديد أي نص باستخدام الماوس ؛ ستحتفظ المكالمة .SelectAll () بالكتابة فوق تحديد نص المستخدم.

لا يعمل استدعاء BeginInvoke ((Action) textbox.SelectAll) على التركيز / دخول الحدث enter لأنه يخرق القاعدة # 2 أعلاه ، فإنه سيبقي على اختيار المستخدم في التركيز.




هذا يعمل لي في .NET 2005 -

    ' * if the mouse button is down, do not run the select all.
    If MouseButtons = Windows.Forms.MouseButtons.Left Then
        Exit Sub
    End If

 ' * OTHERWISE INVOKE THE SELECT ALL AS DISCUSSED.



ومن المثير للاهتمام ، و ComboBox مع DropDownStyle = بسيط لديه حد كبير بالضبط السلوك الذي تبحث عنه ، على ما أعتقد.

(إذا قمت بتقليل ارتفاع عنصر التحكم لعدم إظهار القائمة - ثم ببضع وحدات بكسل أكثر - لا يوجد فرق فعال بين ComboBox و TextBox.)




أعلم أن هذا قد تم حله بالفعل ولكن لدي اقتراح أعتقد أنه بسيط للغاية.

في الفأرة حدث كل ما عليك القيام به هو المكان

if(textBox.SelectionLength = 0)
{
    textBox.SelectAll();
}

يبدو لي العمل في VB.NET (أنا أعرف هذا سؤال C # ... للأسف أنا مجبرة على استخدام VB في وظيفتي .. وكان لدي هذه المسألة ، وهو ما جلب لي هنا ... )

لم أجد أي مشاكل معها حتى الآن ... باستثناء حقيقة أنه لا يختار على الفور بمجرد النقر ، ولكن كنت أواجه مشاكل مع ذلك ....




هذا العمل ل WPF / XAML TextBox.

    private bool initialEntry = true;
    private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
    {
        if (initialEntry)
        {
            e.Handled = true;
            initialEntry = false;
            TextBox.SelectAll();
        }
    }
    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox.SelectAll();
        initialEntry = true;      
    }



لمجموعة من مربعات النص في نموذج:

private System.Windows.Forms.TextBox lastFocus;   

private void textBox_GotFocus(object sender, System.Windows.Forms.MouseEventArgs e)   
{
    TextBox senderTextBox = sender as TextBox;
    if (lastFocus!=senderTextBox){
        senderTextBox.SelectAll();
    }
    lastFocus = senderTextBox;   
}






ضبط selction عند مغادرة السيطرة. سيكون هناك عند العودة. انقر فوق علامة التبويب حول النموذج وعند الرجوع إلى عنصر التحكم ، سيتم تحديد كافة النص.

إذا دخلت بالماوس ، فسيتم وضع علامة الإقحام في المكان الذي قمت بالنقر فوقه.

private void maskedTextBox1_Leave(object sender, CancelEventArgs e)
    {
        maskedTextBox1.SelectAll();
    }



أجد هذا العمل أفضل ، عند النقر بالماوس وعدم الإفراج عنه على الفور:

    private bool SearchBoxInFocusAlready = false;
    private void SearchBox_LostFocus(object sender, RoutedEventArgs e)
    {
        SearchBoxInFocusAlready = false;
    }

    private void SearchBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (e.ButtonState == MouseButtonState.Released && e.ChangedButton == MouseButton.Left &&
            SearchBox.SelectionLength == 0 && SearchBoxInFocusAlready == false)
        {
            SearchBox.SelectAll();
        }

        SearchBoxInFocusAlready = true;
    }



حل بسيط جدا:

    private bool _focusing = false;

    protected override void OnEnter( EventArgs e )
    {
        _focusing = true;
        base.OnEnter( e );
    }

    protected override void OnMouseUp( MouseEventArgs mevent )
    {
        base.OnMouseUp( mevent );

        if( _focusing )
        {
            this.SelectAll();
            _focusing = false;
        }
    }

EDIT: كان OP الأصلي مهتمًا بشكل خاص بتسلسل الفأرة / اختيار النص / الماوس إلى أعلى ، وفي هذه الحالة سينتهي الأمر بالحل البسيط أعلاه بنص يتم اختياره جزئيًا.

يجب أن يحل هذا المشكلة * (في الممارسة أنا اعتراض WM_SETCURSOR):

    protected override void WndProc( ref Message m )
    {
        if( m.Msg == 32 ) //WM_SETCURSOR=0x20
        {
              this.SelectAll(); // or your custom logic here                
        }

        base.WndProc( ref m );
    }

* في الواقع ، ينتهي التسلسل التالي بنص جزئي ، ولكن إذا قمت بتحريك الماوس فوق مربع النص ، فسيتم تحديد كل النص مرة أخرى:

الفأرة لأسفل / تحديد النص / الفأرة - تحريك - خارج - textbox / mouse-up




وهنا وظيفة المساعد مع الحل إلى المستوى التالي - إعادة الاستخدام دون الوراثة.

    public static void WireSelectAllOnFocus( TextBox aTextBox )
    {
        bool lActive = false;
        aTextBox.GotFocus += new EventHandler( ( sender, e ) =>
        {
            if ( System.Windows.Forms.Control.MouseButtons == MouseButtons.None )
            {
                aTextBox.SelectAll();
                lActive = true;
            }
        } );

        aTextBox.Leave += new EventHandler( (sender, e ) => {
            lActive = false;
        } );

        aTextBox.MouseUp += new MouseEventHandler( (sender, e ) => {
            if ( !lActive )
            {
                lActive = true;
                if ( aTextBox.SelectionLength == 0 ) aTextBox.SelectAll();
            }   
        });
    }

لاستخدام هذا ببساطة استدعاء الدالة تمرير مربع نص ويعتني كافة بت فوضوي لك. أقترح توصيل جميع مربعات النص في الحدث Form_Load. يمكنك وضع هذه الوظيفة في النموذج الخاص بك ، أو إذا كان مثلي ، في مكان ما في فصل دراسي من أجل إعادة استخدام أكثر.




لقد وجدت حلا أبسط:

للتأكد من تحديد كافة النص عند النقر فوق مربع نص ، تأكد من أن "معالج النقر" يستدعي معالج "الإدخال". لا حاجة لمتغيرات إضافية!

مثال:

private void textBox1_Click(object sender, EventArgs e){
        textBox1_Enter(sender, e);
    }

private void textBox1_Enter(object sender, EventArgs e){
        TextBox tb = ((TextBox)sender);
        tb.SelectAll();
    }



إجابة سطر واحد أستخدمها ... قد تكون ركل نفسك ...

في أدخل الحدث:

txtFilter.BeginInvoke (new MethodInvoker (txtFilter.SelectAll))؛




إنها kludgey صغيرة ، ولكن في حدث النقر الخاص بك ، استخدم SendKeys.Send( "{HOME}+{END}" ); .




دعوت SelectAll داخل حدث MouseUp وأنها عملت بشكل جيد بالنسبة لي.

    private bool _tailTextBoxFirstClick = false;

    private void textBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if(_textBoxFirstClick)           
            textBox1.SelectAll();

        _textBoxFirstClick = false;
    }  

    private void textBox1_Leave(object sender, EventArgs e)
    {
        _textBoxFirstClick = true;
        textBox1.Select(0, 0);
    }



Related