การทำให้กล่องข้อความ WinForms ทำงานเหมือนแถบที่อยู่ของเบราว์เซอร์ของคุณ


154

เมื่อกล่องข้อความ C # WinForms ได้รับการโฟกัสฉันต้องการให้มันทำงานเหมือนแถบที่อยู่ของเบราว์เซอร์ของคุณ

หากต้องการดูว่าฉันหมายถึงอะไรให้คลิกในแถบที่อยู่ของเว็บเบราว์เซอร์ของคุณ คุณจะสังเกตเห็นพฤติกรรมดังต่อไปนี้:

  1. การคลิกในกล่องข้อความควรเลือกข้อความทั้งหมดหากไม่ได้เน้นข้อความไว้ก่อนหน้านี้
  2. เลื่อนเมาส์ลงและลากในกล่องข้อความควรเลือกเฉพาะข้อความที่ฉันเน้นด้วยเมาส์
  3. หากกล่องข้อความนั้นโฟกัสอยู่แล้วการคลิกจะไม่เลือกข้อความทั้งหมด
  4. การโฟกัสกล่องข้อความโดยทางโปรแกรมหรือผ่านแท็บคีย์บอร์ดควรเลือกข้อความทั้งหมด

ฉันต้องการทำสิ่งนี้ใน WinForms

ALUN GUN ALERT: โปรดอ่านข้อความต่อไปนี้ก่อนตอบ! ขอบคุณเพื่อน. :-)

การเรียก. SelectAll () ระหว่างเหตุการณ์. ใส่หรือ .GotFocus จะไม่ทำงานเพราะหากผู้ใช้คลิกที่กล่องข้อความเครื่องหมายรูปหมวกจะถูกวางไว้ในตำแหน่งที่เขาคลิกดังนั้นจึงยกเลิกการเลือกข้อความทั้งหมด

การโทร. SelectAll () ระหว่างกิจกรรม .Click จะไม่ทำงานเนื่องจากผู้ใช้จะไม่สามารถเลือกข้อความใด ๆ ด้วยเมาส์ การเรียกใช้. SelectAll () จะแทนที่การเลือกข้อความของผู้ใช้

การเรียกกล่องข้อความ BeginInvoke (Action) SelectAll) ที่โฟกัส / เข้าสู่การป้อนเหตุการณ์ไม่ทำงานเพราะมันทำลายกฎ # 2 ด้านบนมันจะยกเลิกการเลือกของผู้ใช้ในการโฟกัส


3
โปรดอธิบายสิ่งนี้สำหรับ "RichTextBox"
Nescio

Nescio, กล่องข้อความหรือกล่องข้อความสมบูรณ์จะทำ ฉันลองวิธีแก้ปัญหาของคุณในกล่องข้อความด้วย
Judah Gabriel Himango

นี่คือสิ่งที่เป็นนามธรรมรั่วไหล วิธีที่ดีที่สุดในการตั้งค่าสถานะ WM_MOUSEACTIVATE และ SelectAll บน WM_SETFOCUS หากไม่ใช่ WM_MOUSEACTIVATE
wqw

เวอร์ชั่น WPF: stackoverflow.com/questions/4161531/…
Jonathan Allen

คำตอบ:


109

ก่อนอื่นขอขอบคุณสำหรับคำตอบ! 9 คำตอบทั้งหมด ขอบคุณ.

ข่าวร้าย: คำตอบทั้งหมดมีนิสัยใจคอบ้างหรือไม่ดีนัก (หรือเลย) ฉันได้เพิ่มความคิดเห็นในแต่ละโพสต์ของคุณ

ข่าวดี: ฉันพบวิธีที่จะทำให้มันใช้ได้ วิธีการแก้ปัญหานี้ค่อนข้างตรงไปตรงมาและดูเหมือนว่าจะทำงานในทุกสถานการณ์ (เลื่อนเมาส์เลือกข้อความแท็บโฟกัส ฯลฯ )

bool alreadyFocused;

...

textBox1.GotFocus += textBox1_GotFocus;
textBox1.MouseUp += textBox1_MouseUp;
textBox1.Leave += textBox1_Leave;

...

void textBox1_Leave(object sender, EventArgs e)
{
    alreadyFocused = false;
}


void textBox1_GotFocus(object sender, EventArgs e)
{
    // Select all text only if the mouse isn't down.
    // This makes tabbing to the textbox give focus.
    if (MouseButtons == MouseButtons.None)
    {
        this.textBox1.SelectAll();
        alreadyFocused = true;
    }
}

void textBox1_MouseUp(object sender, MouseEventArgs e)
{
    // Web browsers like Google Chrome select the text on mouse up.
    // They only do it if the textbox isn't already focused,
    // and if the user hasn't selected all text.
    if (!alreadyFocused && this.textBox1.SelectionLength == 0)
    {
        alreadyFocused = true;
        this.textBox1.SelectAll();
    }
}

เท่าที่ฉันสามารถบอกได้สิ่งนี้ทำให้กล่องข้อความทำงานเหมือนกับแถบที่อยู่ของเว็บเบราว์เซอร์

หวังว่านี่จะช่วยให้คนต่อไปที่พยายามแก้ปัญหานี้อย่างหลอกลวง

ขอบคุณอีกครั้งสำหรับคำตอบทั้งหมดของคุณที่ช่วยพาฉันไปสู่เส้นทางที่ถูกต้อง


สิ่งที่เกี่ยวกับเมื่อมีการตั้งค่าโฟกัสโดยทางโปรแกรมเป็นกล่องข้อความ? ฉันมีปัญหาดังที่กล่าวไว้ที่นี่: stackoverflow.com/questions/24790704/ ......ฉันสามารถแก้ไขได้หลังจากแฟชั่น แต่ฉันยังกังวลเกี่ยวกับเรื่องนี้เพราะ "การแก้ไข" ของฉันดูเหมือนว่าค่อนข้างขี้เกียจ
B. Clay Shannon

คุณเขียนว่า "การโทร. SelectAll () ระหว่างกิจกรรม. Enter หรือ. GotFocus จะไม่ทำงานเพราะหากผู้ใช้คลิกที่กล่องข้อความเครื่องหมายรูปหมวกจะถูกวางไว้ในตำแหน่งที่เขาคลิกดังนั้นจึงเป็นการเลือกข้อความทั้งหมด" ฉันมี SelectAll ในเหตุการณ์ GotFocus ซึ่งส่วนใหญ่ทำงานได้ ในความเป็นจริงฉันคิดว่าเคอร์เซอร์ถูกวางไว้ในตำแหน่งที่ผู้ใช้คลิกคือ "สิ่งที่ดี" ฉันแค่อยากให้มันถูกเลือกเสมอเมื่อตั้งโฟกัสไว้ที่กล่องข้อความโดยทางโปรแกรม
B. Clay Shannon

และฉันมาที่นี่อีกครั้ง! :)
dotNET

3
คุณควรย้ายalreadyFocused = true;ใน MouseUp จากคำสั่ง if เพราะหากคุณเลือกส่วนของข้อความได้ทันทีการคลิกครั้งต่อไปจะเป็นการเลือกข้อความทั้งหมดอีกครั้ง
Robert S.

มีคำตอบหนึ่งซับด้านล่าง --- BeginInvoke ((Action) MyTextBox.SelectAll); --- น่าดู ดูเหมือนว่าจะทำทุกสิ่งที่จำเป็น
นายพลเกรย์

78

ฉันพบวิธีแก้ปัญหาที่ง่ายกว่านี้ มันเกี่ยวข้องกับการเริ่มต้น 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

5
คำตอบที่ฉลาดที่สุดที่ผมเคยพบเคย .. ขอบคุณมาก .. สำหรับ VB.net นี่เป็นทางออกที่ .. Private Sub MyTextBox_Enter(sender As Object, e As EventArgs) Handles MyTextBox.Enter BeginInvoke(DirectCast(Sub() MyTextBox.SelectAll(), Action)) End Sub
คริชานูเดย์

ทางออกที่ดีที่สุดของ Class Much 'เช่นแถบ URL ของเว็บเบราว์เซอร์ระดับ End Class มาก
ar.dll

7
ใน. Net 4.0 คุณสามารถทำได้: BeginInvoke ((Action) MyTextBox.SelectAll);
JoelFan

2
น่าเสียดายที่ BeginInvoke ไม่สามารถใช้งานได้สำหรับฉัน กำลังเตรียม "ควบคุม" มันไม่ได้ช่วยหรือไม่ได้เตรียมชื่อของกล่องข้อความเอง อยู่คนเดียวและพูดจาโผงผางอย่างรุนแรง
บี. Clay Shannon

2
โปรดทราบว่าโซลูชันนี้ไม่ทำงานตามที่อธิบายไว้ในคำถาม โดยเฉพาะMouse down and drag in the textbox should select only the text I've highlighted with the mouse.ไม่ทำงานอย่างที่ต้องการ แต่ก็ยังคงที่สั้นที่สุดและสง่างามมากที่สุดในการแก้ปัญหา :)
มาร์คัส Mangelsdorf

30

วิธีแก้ปัญหาของคุณดี แต่ล้มเหลวในบางกรณี หากคุณให้ความสำคัญกับกล่องข้อความโดยเลือกช่วงของข้อความแทนการคลิกเพียงแค่ธงโฟกัสแล้วไม่ได้รับการตั้งค่าเป็นจริงดังนั้นเมื่อคุณคลิกในกล่องข้อความเป็นครั้งที่สองข้อความทั้งหมดจะถูกเลือก

นี่คือโซลูชันของฉัน ฉันยังใส่รหัสลงในคลาสที่สืบทอดกล่องข้อความดังนั้นตรรกะจึงถูกซ่อนไว้อย่างดี

public class MyTextBox : System.Windows.Forms.TextBox
{
    private bool _focused;

    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        if (MouseButtons == MouseButtons.None)
        {
            SelectAll();
            _focused = true;
        }
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        _focused = false;
    }

    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        base.OnMouseUp(mevent);
        if (!_focused)
        {
            if (SelectionLength == 0)
                SelectAll();
            _focused = true;
        }
    }
}

2
+1 สำหรับคำแนะนำช่องข้อความที่กำหนดเองและวิธีการทำงานที่สมบูรณ์แบบ!
Fueled

โซลูชั่นที่ยอดเยี่ยม คัดลอกรหัสของคุณลงในโซลูชันของฉันเปลี่ยนเนมสเปซเพื่อปกป้องผู้บริสุทธิ์และทำงานได้อย่างสมบูรณ์ ขอบคุณ!
kenswdev

8

มันค่อนข้างแออัดเกินไปเล็กน้อย SendKeys.Send( "{HOME}+{END}" );แต่ในคลิกเหตุการณ์ของการใช้งาน


Woofta! นั่นเป็นบิตของการแฮ็ก! :-) ขอบคุณสำหรับคำแนะนำ มีความคิดที่ดีกว่านี้ไหม?
Judah Gabriel Himango

การแฮ็กจริง ๆ แต่สิ่งนี้ฟังดูไม่เลวเลย
เทอร์รี่

3
พิจารณาว่าโปรแกรมต่อต้านไวรัสจำนวนมากสกัดกั้นและบล็อก SEND KEYS ว่าเป็นอันตราย มันไม่ใช่ทางออกที่ดี
Judah Gabriel Himango

4

คลิกเหตุการณ์ของกล่องข้อความ? หรือแม้แต่เหตุการณ์ MouseCaptureChanged ก็ใช้ได้สำหรับฉัน - ตกลง. ไม่ทำงาน

ดังนั้นคุณต้องทำ 2 สิ่ง:

private bool f = false;

private void textBox_MouseClick(object sender, MouseEventArgs e)
{ 
  if (this.f) { this.textBox.SelectAll(); }
  this.f = false;
}

private void textBox_Enter(object sender, EventArgs e)
{
  this.f = true;
  this.textBox.SelectAll();
}
private void textBox_MouseMove(object sender, MouseEventArgs e) // idea from the other answer
{
  this.f = false; 
}

ใช้งานได้กับการแท็บ (ผ่านกล่องข้อความถึงหนึ่ง) เช่นกัน - เรียกใช้ SelectAll () ใน Enter เพียงแค่ในกรณี ...


Ok Jakub นั่นใช้งานได้บางส่วน ถ้าฉันแท็บไปที่กล่องข้อความมันต้องโฟกัส มันจะใช้งานได้กับโซลูชั่นของคุณหรือไม่ (ถ้าคุณสามารถแสดงฉันว่าฉันจะทำเครื่องหมายคำตอบของคุณเป็นคำตอบที่ถูกต้อง.)
ยูดาห์กาเบรียล Himango

Jakub ตอนนี้คุณได้โพสต์โค้ดแล้วบางครั้งมันก็ใช้งานได้ ไม่เสมอ; ตอนนี้ฉันคลิกเข้าไปในกล่องข้อความและมันไม่ได้เลือกทั้งหมด
Judah Gabriel Himango

บางครั้งฉันจะคลิกเข้าไปในข้อความ แต่ไม่ได้เลือกทั้งหมด มันก็เหมือนอย่างใดฟิลด์. f ไม่ได้ถูกตั้งค่าเป็นสิ่งที่ควรและจากนั้น SelectAll จะไม่ถูกเรียก ยังไม่เห็นสิ่งนี้ใช่ไหม
Judah Gabriel Himango

ฉันรู้เพียงว่าเพราะ mouseMouve คุณสามารถคลิกช้าในขณะที่เลื่อนเมาส์ (โดยเฉพาะตัวอักษรกว้าง) -> ยกเลิกการตั้งค่าสถานะ คุณสามารถลบรหัสในเหตุการณ์ mouseMove แต่หลังจากที่คุณได้รับ - หลังจาก tabbgin เพื่อควบคุมแล้วคลิก - reSelectAll - ไม่สามารถเลือกส่วนหนึ่งของการกวนในการลากครั้งแรก
Jakub Kotrla

4

คำตอบหนึ่งบรรทัดที่ฉันใช้ ... คุณอาจจะเตะตัวเอง ...

ในการเข้าร่วมกิจกรรม:

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


1
ไม่ไม่ทำงาน มันเลือกข้อความทั้งหมดไม่เป็นไร แต่ก็ป้องกันผู้ใช้จากการเลือกเพียงส่วนหนึ่งของข้อความท่ามกลางปัญหาอื่น ๆ
Judah Gabriel Himango

ขออภัยฉันต้องเข้าใจพฤติกรรมที่คุณมองหาผิด เมื่อเข้าสู่การเลือกทั้งหมดถ้าคุณคลิกค้างไว้เลือกจากเริ่มต้นที่เคอร์เซอร์ของคุณ ฉันคิดว่าคุณสามารถใช้สิ่งที่ฉันมีและแทนที่ SelectAll ด้วยตรรกะการเลือกของคุณเอง alertwire.com/demos/2009-04-14_1248.swf

ใช้งานได้ดี! คลิกครั้งแรกที่เข้าสู่กล่อง; จากนั้นคลิกและลากเพื่อเลือกข้อความ
D_Bester

หมายเหตุ: มันไม่ทำงานเหมือนแถบที่อยู่ของเว็บเบราว์เซอร์ แถบที่อยู่ของเว็บเบราว์เซอร์ช่วยให้คุณสามารถวางเมาส์ลงในกล่องข้อความและลาก / เลือกแม้ในขณะที่กล่องข้อความยังไม่มีโฟกัส วิธีนี้ไม่ได้แก้ปัญหานั้น หากคุณตกลงกับมันเจ๋ง แต่ไม่เป็นไปตามข้อกำหนดของคำถามนี้
Judah Gabriel Himango

3
'Inside the Enter event
TextBox1.SelectAll();

ตกลงหลังจากลองที่นี่เป็นสิ่งที่คุณต้องการ:

  • ในการบันทึกเหตุการณ์เริ่มต้นการตั้งค่าสถานะที่ระบุว่าคุณอยู่ในเหตุการณ์ใส่
  • ในเหตุการณ์คลิกถ้าคุณตั้งค่าสถานะโทร. SelectAll () และตั้งค่าสถานะใหม่
  • ในเหตุการณ์ MouseMove ให้ตั้งค่าสถานะที่ป้อนเป็นเท็จซึ่งจะช่วยให้คุณคลิกไฮไลต์โดยไม่ต้องป้อนกล่องข้อความก่อน

สิ่งนี้เลือกข้อความทั้งหมดที่อยู่ในรายการ แต่อนุญาตให้ฉันไฮไลต์ส่วนของข้อความหลังจากนั้นหรืออนุญาตให้คุณไฮไลต์เมื่อคลิกครั้งแรก

ตามการร้องขอ:

    bool entered = false;
    private void textBox1_Enter(object sender, EventArgs e)
    {
        entered = true;
        textBox1.SelectAll();   //From Jakub's answer.
    }

    private void textBox1_Click(object sender, EventArgs e)
    {
        if (entered) textBox1.SelectAll();
        entered = false;
    }

    private void textBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (entered) entered = false;
    }

สำหรับฉันแท็บในตัวควบคุมจะเลือกข้อความทั้งหมด


โซลูชันของคุณคล้ายกับโซลูชันของ Jakub มันทำงานสำหรับการคลิก มันสามารถทำงานได้เมื่อแท็บไปที่กล่องข้อความ? (เช่นการแท็บที่แถบที่อยู่ของเบราว์เซอร์จะเลือกข้อความทั้งหมดด้วย)
Judah Gabriel Himango

ใช่มันใช้งานได้กับการแท็บด้วย ฉันเขียนแอพทดสอบและนี่คือวิธีที่ฉันใช้งานได้
MagicKat

ดูเหมือนจะใช้การแท็บไม่ได้ คุณช่วยแสดงรหัสที่ใช้ในการแท็บให้เราได้ไหม
Judah Gabriel Himango

3

นี่คือฟังก์ชั่นผู้ช่วยเหลือที่นำโซลูชันไปสู่ระดับถัดไป - นำมาใช้ใหม่โดยไม่มีการสืบทอด

    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 คุณสามารถวางฟังก์ชั่นนี้ในแบบฟอร์มของคุณหรือถ้าชอบฉันที่ใดที่หนึ่งในคลาสยูทิลิตี้สำหรับการใช้ซ้ำมากขึ้น


2

สิ่งนี้ใช้ได้กับกล่องข้อความ WPF / XAML

    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;      
    }

2

นี่คล้ายกับคำตอบที่ได้รับความนิยมของnzhenryแต่ฉันคิดว่ามันง่ายกว่าที่จะไม่ต้อง subclass:

Private LastFocused As Control = Nothing

Private Sub TextBox1_Enter(sender As Object, e As System.EventArgs) Handles TextBox1.Enter, TextBox2.Enter, TextBox3.Enter
    If MouseButtons = Windows.Forms.MouseButtons.None Then LastFocused = sender
End Sub

Private Sub TextBox1_Leave(sender As Object, e As System.EventArgs) Handles TextBox1.Leave, TextBox2.Leave, TextBox3.Leave
    LastFocused = Nothing
End Sub

Private Sub TextBox1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseUp, TextBox2.MouseUp, TextBox3.MouseUp
    With CType(sender, TextBox)
        If LastFocused IsNot sender AndAlso .SelectionLength = 0 Then .SelectAll()
    End With
    LastFocused = sender
End Sub

1

SelectAll ไม่เคยทำงานให้ฉัน

วิธีนี้ใช้ได้ผล

ActiveControl = textBox1;
textBox1->SelectionStart = 0;
textBox1->SelectionLength = textBox1->Text->Length;

แต่นั่นไม่ได้คำนึงถึงกรณีที่การแท็บลงในช่องนำความสนใจ นอกจากนี้ยังแสดงปัญหาอื่น ๆ ที่กล่าวถึงในหัวข้อนี้
ยูดาห์กาเบรียล Himango

1

ฉันได้พบวิธีแก้ปัญหาที่ง่ายยิ่งขึ้น:

เพื่อให้แน่ใจว่าข้อความทั้งหมดถูกเลือกเมื่อคลิกที่กล่องข้อความตรวจสอบให้แน่ใจว่าตัวจัดการคลิกเรียกใช้ตัวจัดการการป้อน ไม่จำเป็นต้องมีตัวแปรเพิ่มเติม!

ตัวอย่าง:

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();
    }

สิ่งนี้ใช้ไม่ได้กับการโฟกัสผ่านการแท็บไปยังส่วนควบคุมใช่ไหม นอกจากนี้เมื่อคุณต้องการเลือกข้อความโดยไม่เลือกทั้งหมด
Judah Gabriel Himango

ที่จริงแล้วมันใช้งานได้กับการแท็บมัน! ฉันเพิ่งทดสอบในโครงการจำลองโดยใช้ MS Visual C # 2010 สิ่งที่น่ารำคาญกับโซลูชันนี้คือคุณไม่สามารถเลือกข้อความโดยไม่เลือกทั้งหมด หากคุณต้องการทำเช่นนั้นแน่นอนว่าไม่จำเป็นต้องใช้รหัสคุณสามารถใช้เมาส์แล้วเลือก (หรือใช้แป้นพิมพ์)
Pieter Heemeryck

และนี่คือสาเหตุที่โซลูชันนี้ไม่สามารถแก้ปัญหาที่เกิดขึ้นได้: มันไม่ทำงานเหมือนกล่องที่อยู่ของเบราว์เซอร์เนื่องจากคุณไม่สามารถคลิกแต่ละส่วนของที่อยู่ได้หากไม่ได้เลือกข้อความทั้งหมด
ยูดาห์กาเบรียล Himango

ตกลงฉันเห็นสิ่งที่คุณหมายถึง ชื่อของคำถามและตัวอย่างแถบที่อยู่ของเว็บเบราว์เซอร์ไม่ได้ระบุว่าคุณควรเลือกข้อความบางส่วนได้ คุณพูดถึงสิ่งนี้เป็นเพียงประโยคเดียวในประโยคสุดท้ายของคำถามของคุณ ความนับถือ.
Pieter Heemeryck

0
private bool _isSelected = false;
private void textBox_Validated(object sender, EventArgs e)
{
    _isSelected = false;
}

private void textBox_MouseClick(object sender, MouseEventArgs e)
{
    SelectAllText(textBox);
}

private void textBox_Enter(object sender, EventArgs e)
{
    SelectAllText(textBox);
}

private void SelectAllText(TextBox text)
{
    if (!_isSelected)
    {
        _isSelected = true;
        textBox.SelectAll();
    }
}

ฉันเพิ่งทดสอบด้วย RichTextBox ใช้งานไม่ได้ การคลิกเข้าไปในกล่องข้อความจะไม่ปรากฏขึ้นเพื่อเลือกข้อความทั้งหมด (เพราะมันจะถูกยกเลิกการเลือกบนเมาส์ลงเมื่อเครื่องหมายรูปหมวกวางไว้ที่เคอร์เซอร์.)
ยูดาห์กาเบรียล Himango

0

น่าสนใจ ComboBox ที่มี DropDownStyle = Simple มีลักษณะที่คุณต้องการอย่างมาก

(ถ้าคุณลดความสูงของตัวควบคุมเพื่อไม่ให้แสดงรายการ - แล้วเพิ่มอีกสองสามพิกเซล - ไม่มีความแตกต่างที่มีประสิทธิภาพระหว่าง ComboBox และกล่องข้อความ)


ที่น่าสนใจ แต่ฉันต้องการสิ่งนี้เพื่อทำงานกับ TextBox และ RichTextBox
ยูดาห์กาเบรียล Himango

0

ทำไมคุณไม่ใช้ MouseDown-Event ของกล่องข้อความ มันใช้งานได้ดีสำหรับฉันและไม่ต้องการบูลีนเพิ่มเติม สะอาดและเรียบง่ายมากเช่น:

private void textbox_MouseDown(object sender, MouseEventArgs e) {
    if (textbox != null && !string.IsNullOrEmpty(textbox.Text))
    {
        textbox.SelectAll();
    } }

ไม่, มีปัญหาสองสามอย่างนี้: ไม่ได้คำนึงถึงว่ากล่องข้อความนั้นมีโฟกัสอยู่แล้ว (เราไม่ต้องการที่จะเลือก - ทุกเม้าส์ลง, เมื่อกล่องข้อความไม่มีโฟกัส), ไม่อนุญาตให้คุณเลือกเพียงแค่ ส่วนของข้อความไม่ทำงานเมื่อนำโฟกัสผ่านการแท็บไปยังกล่องข้อความ
Judah Gabriel Himango

0

ฉันเรียกว่า 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);
    }

ใช่ดูคำตอบอื่น ๆ (และความคิดเห็น) เพราะเหตุนี้ไม่สามารถใช้งานได้ในทุกสถานการณ์
ยูดาห์กาเบรียล Himango

ฉันไม่ได้ตรวจสอบแท็บสำหรับโซลูชันนี้ ความผิดฉันเอง. ขอบคุณสำหรับการชี้ให้เห็น ดีใจที่เห็นว่าคุณมีทางออกที่สมบูรณ์แล้ว และยังดีใจที่ได้ทราบว่าข้อเสนอแนะของฉันสำหรับ MouseUp ได้รวมอยู่ในโซลูชันของคุณแล้ว
Sreejith K.

0

เพียงรับคลาสจาก TextBox หรือ MaskedTextBox:

public class SMaskedTextBox : MaskedTextBox
{
    protected override void OnGotFocus(EventArgs e)
    {
        base.OnGotFocus(e);
        this.SelectAll();
    }
}

และใช้ในแบบฟอร์มของคุณ


มันใช้งานไม่ได้ เพื่อทำความเข้าใจว่าทำไมดูคำตอบและความคิดเห็นอื่น ๆ
ยูดาห์กาเบรียล Himango

0

คุณได้ลองวิธีแก้ปัญหาที่แนะนำในฟอรัม MSDN "Windows Forms General"ซึ่งเพียงแค่ subclasses Text หรือไม่?


ฉันเชื่อว่าเราพยายามอย่างนั้น อย่างไรก็ตามฉันไม่จำข้อบกพร่องด้วยโซลูชันนั้น
ยูดาห์กาเบรียล Himango

0

ที่จริงแล้ว GotFocus เป็นเหตุการณ์ที่เหมาะสม (ข้อความจริง ๆ ) ที่คุณสนใจเพราะไม่ว่าคุณจะเข้าควบคุมได้อย่างไรคุณก็จะได้สิ่งนี้แม้ในที่สุด คำถามคือเมื่อใดที่คุณโทรถึง SelectAll ()

ลองสิ่งนี้:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.textBox1.GotFocus += new EventHandler(textBox1_GotFocus);
    }

    private delegate void SelectAllDelegate();    
    private IAsyncResult _selectAllar = null; //So we can clean up afterwards.

    //Catch the input focus event
    void textBox1_GotFocus(object sender, EventArgs e)
    {
        //We could have gotten here many ways (including mouse click)
        //so there could be other messages queued up already that might change the selection.
        //Don't call SelectAll here, since it might get undone by things such as positioning the cursor.
        //Instead use BeginInvoke on the form to queue up a message
        //to select all the text after everything caused by the current event is processed.
        this._selectAllar = this.BeginInvoke(new SelectAllDelegate(this._SelectAll));
    }

    private void _SelectAll()
    {
        //Clean-up the BeginInvoke
        if (this._selectAllar != null)
        {
            this.EndInvoke(this._selectAllar);
        }
        //Now select everything.
        this.textBox1.SelectAll();
    }
}

อาลีนี่ใช้งานไม่ได้ ลองวางเมาส์ไว้กลางข้อความ กดปุ่มเมาส์ค้างไว้ 1 วินาที
Judah Gabriel Himango

0

สำหรับกลุ่มกล่องข้อความในรูปแบบ:

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;   
}

1
สิ่งนี้ทำงานไม่ถูกต้อง ดูคำตอบของฉันสำหรับคำตอบอื่น ๆ ที่แนะนำ. SelectAll () มันไม่ทำงานเพราะถ้าคุณป้อนกล่องข้อความในขณะที่พยายามเลือกข้อความมันจะแบ่งการเลือกข้อความของคุณโดยการเลือกข้อความทั้งหมด คุณต้องการเลือกข้อความเฉพาะเมื่อโฟกัสเข้าสู่กล่องข้อความด้วยเมาส์ขึ้นหรือแท็บลงในนั้น แต่ถ้าโฟกัสเกิดจากการเลื่อนเมาส์ลง
ยูดาห์กาเบรียล Himango

0

ฉันรู้ว่านี่ถูกแก้ไขแล้ว แต่ฉันมีข้อเสนอแนะที่ฉันคิดว่าจริง ๆ แล้วค่อนข้างง่าย

ในเหตุการณ์เลื่อนเม้าส์สิ่งที่คุณต้องทำคือวาง

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

ดูเหมือนว่าจะทำงานให้ฉันใน VB.NET (ฉันรู้ว่านี่เป็นคำถาม C # ... น่าเศร้าที่ฉันถูกบังคับให้ใช้ VB ในงานของฉัน .. และฉันมีปัญหานี้ซึ่งเป็นสิ่งที่นำฉันมาที่นี่ ... )

ฉันยังไม่พบปัญหาใด ๆ เลย .. ยกเว้นความจริงที่ว่ามันไม่ได้เลือกทันทีเมื่อคลิก แต่ฉันมีปัญหากับมัน ....


1
คำขอเดิมต้องการให้สิ่งนี้ทำงานเมื่อคุณแท็บลงในฟิลด์เช่นกัน
Don Kirkby

2
ใช่นี่ใช้ไม่ได้กับทุกสถานการณ์ มันจะทำงานเฉพาะเมื่อคุณคลิกเข้าไปในกล่องข้อความ และแม้กระทั่งถ้าไม่ได้ทำงานเป็นแถบที่อยู่ของเบราว์เซอร์จะทำงานเมื่อการเลือกมีอยู่แล้วในกล่องข้อความ
ยูดาห์กาเบรียล Himango

0

วิธีแก้ปัญหาต่อไปนี้ใช้ได้กับฉัน ฉันเพิ่มOnKeyDownและOnKeyUpแทนที่เหตุการณ์เพื่อให้ข้อความกล่องข้อความที่เลือกไว้เสมอ

    public class NumericTextBox : TextBox
{
    private bool _focused;
    protected override void OnGotFocus(EventArgs e)
    {
        base.OnGotFocus(e);
        if (MouseButtons == MouseButtons.None)
        {
            this.SelectAll();
            _focused = true;
        }
    }
    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        if (MouseButtons == MouseButtons.None)
        {
            SelectAll();
            _focused = true;
        }
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        _focused = false;
    }

    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        base.OnMouseUp(mevent);
        if (!_focused)
        {
            if (SelectionLength == 0)
                SelectAll();
            _focused = true;
        }
    }

    protected override void OnKeyUp(KeyEventArgs e)
    {
        base.OnKeyUp(e);

        if (SelectionLength == 0)
            SelectAll();
        _focused = true;
    }
    protected override void OnKeyDown(KeyEventArgs e)
    {
       base.OnKeyDown(e);
       if (SelectionLength == 0)
            SelectAll();
        _focused = true;
    }
}

2
มันช่วยให้คุณสามารถวางเมาส์ลงในกล่องข้อความลากเคอร์เซอร์เพื่อเลือกข้อความจากนั้นเลื่อนเมาส์ขึ้น?
Judah Gabriel Himango

0

ตั้งค่า selction เมื่อคุณออกจากการควบคุม มันจะอยู่ที่นั่นเมื่อคุณกลับมา แท็บรอบ ๆ แบบฟอร์มและเมื่อคุณกลับไปที่ตัวควบคุมข้อความทั้งหมดจะถูกเลือก

หากคุณเข้าไปข้างในด้วยเมาส์เครื่องหมายรูปหมวกจะถูกวางในตำแหน่งที่คุณคลิก

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

ถ้าคุณใช้เม้าส์มันควรเลือกข้อความทั้งหมดยกเว้นว่ามันจะถูกโฟกัสไปแล้ว สิ่งนี้ไม่สนับสนุน
ยูดาห์กาเบรียล Himango

0

ทางออกที่ง่ายมาก:

    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;
        }
    }

แก้ไข: 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 );
    }

* อันที่จริงแล้วลำดับต่อไปนี้ลงท้ายด้วยการเลือกข้อความบางส่วน แต่ถ้าคุณเลื่อนเมาส์ไปที่กล่องข้อความข้อความทั้งหมดจะถูกเลือกอีกครั้ง:

mouse-down / text-selection / mouse-move-out-textbox / mouse-up


โซลูชันนี้ได้รับการโพสต์แล้ว ดูความคิดเห็นต่อคำตอบที่มีอยู่เพื่อค้นหาสาเหตุที่ใช้ไม่ได้
Judah Gabriel Himango

ใช้งานได้กับแท็บและด้วยเมาส์คุณสามารถโฟกัสเลือกข้อความแล้วเลื่อนเมาส์ขึ้น ฉันดูเหมือนจะไม่พบปัญหากับสิ่งนี้ คุณช่วยชี้จุดนั้นออกมาได้ไหม
Mauro Sampietro

0

ฉันพบว่ามันทำงานได้ดีที่สุดเมื่อคลิกเมาส์และไม่ปล่อยทันที:

    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;
    }

0

โซลูชันของฉันค่อนข้างดั้งเดิม แต่ทำงานได้ดีสำหรับวัตถุประสงค์ของฉัน

private async void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (sender is TextBox)
    {
        await Task.Delay(100);
        (sender as TextBox).SelectAll();
    }
}

ไม่ทำงานเมื่อคุณต้องการเลื่อนเมาส์ลงเพื่อเลือกข้อความจำนวนมากลากเมาส์แล้วเลื่อนเมาส์ขึ้น รหัสของคุณจะล้างการเลือกและเลือกทุกอย่าง
Judah Gabriel Himango

@JudahHimango Jup หากคุณคลิกเพียงครั้งเดียวมันจะเลือกทุกอย่าง หากคุณคลิกและลากมันจะเลือกเฉพาะส่วนที่เลือก อย่างน้อย Browserbar ใน Firefox แสดงพฤติกรรมนี้อย่างแน่นอน
BlueWizard

มันไม่ได้เป็นเงื่อนไขการแข่งขันใช่มั้ย หากฉันจัดการเพื่อเลือกข้อความอย่างรวดเร็วด้วยเมาส์ดังนั้น. SelectAll () จะเริ่มทำงานในเวลาต่อมาเป็นมิลลิวินาทีเขียนทับการเลือกของฉัน
Judah Gabriel Himango

1
ตกลงถ้าคุณเลือกสิ่งที่รวดเร็วกว่าสิ่งนี้จะทำงานกับคุณ
BlueWizard

-1

ด้านล่างดูเหมือนว่าจะทำงาน เหตุการณ์ป้อนจัดการแท็บไปยังตัวควบคุมและ MouseDown จะทำงานเมื่อมีการคลิกตัวควบคุม

    private ########### void textBox1_Enter(object sender, EventArgs e)
    {
        textBox1.SelectAll();
    }

    private void textBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (textBox1.Focused)
            textBox1.SelectAll();
    }

ไม่โชคไม่ทำงานฉันกลัว ลองเลือกข้อความ ข้อความ. SelectAll จะเขียนทับสิ่งที่ผู้ใช้พยายามเลือก
Judah Gabriel Himango

-1

คำตอบนั้นง่ายกว่าทั้งหมดข้างต้นตัวอย่างเช่น (ใน WPF):

public void YourTextBox_MouseEnter(object sender, MouseEventArgs e)
    {
        YourTextBox.Focus();
        YourTextBox.SelectAll();
    }

แน่นอนว่าฉันไม่รู้วิธีที่คุณต้องการใช้รหัสนี้ แต่ส่วนหลักในการดูที่นี่คือ: สายแรก. โฟกัส () แล้วโทร. เลือกทั้งหมด ();


สิ่งนี้ใช้ไม่ได้และเป็นคำตอบอื่นที่ซ้ำกัน ตัวอย่างเช่นหากคุณวางเมาส์ลงในกล่องข้อความให้ลากมันควรเลือกส่วนของข้อความ สิ่งนี้จะทำลายสิ่งนั้นและจะไม่เลือกทั้งหมด
Judah Gabriel Himango

-1

เพียงแค่ใช้ selectall () เมื่อป้อนและคลิกกิจกรรม

private void textBox1_Enter(object sender, EventArgs e)
        {

            textBox1.SelectAll();
        }
        private void textBox1_Click(object sender, EventArgs e)
        {
            textBox1.SelectAll();
        }

ใช้งานได้จนกว่าคุณต้องการเลือกข้อความ ดูคำตอบอื่น ๆ สำหรับคำอธิบายแบบเต็ม
ยูดาห์กาเบรียล Himango

-1

ฉันสร้างโครงการ VB.Net Wpf ใหม่ ฉันสร้างกล่องข้อความหนึ่งกล่องและใช้โค้ดต่อไปนี้สำหรับโค้ดด้านหลัง:

Class MainWindow 

    Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        AddHandler PreviewMouseLeftButtonDown, New MouseButtonEventHandler(AddressOf SelectivelyIgnoreMouseButton)
        AddHandler GotKeyboardFocus, New KeyboardFocusChangedEventHandler(AddressOf SelectAllText)
        AddHandler MouseDoubleClick, New MouseButtonEventHandler(AddressOf SelectAllText)
    End Sub

    Private Shared Sub SelectivelyIgnoreMouseButton(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        ' Find the TextBox
        Dim parent As DependencyObject = TryCast(e.OriginalSource, UIElement)
        While parent IsNot Nothing AndAlso Not (TypeOf parent Is TextBox)
            parent = VisualTreeHelper.GetParent(parent)
        End While

        If parent IsNot Nothing Then
            Dim textBox As Object = DirectCast(parent, TextBox)
            If Not textBox.IsKeyboardFocusWithin Then
                ' 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
            End If
        End If
    End Sub

    Private Shared Sub SelectAllText(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim textBox As Object = TryCast(e.OriginalSource, TextBox)
        If textBox IsNot Nothing Then
            textBox.SelectAll()
        End If
    End Sub

End Class
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.