[.net] WinForms TextBox를 브라우저의 주소 표시 줄처럼 동작하게 만들기

C # WinForms 텍스트 상자가 포커스를 받으면 브라우저의 주소 표시 줄처럼 작동하기를 원합니다.

무슨 뜻인지 보려면 웹 브라우저의 주소 표시 줄을 클릭하십시오. 다음과 같은 동작이 나타납니다.

  1. 텍스트 상자를 클릭하면 텍스트 상자의 초점이 맞지 않은 경우 모든 텍스트를 선택해야합니다.
  2. 텍스트 상자에서 마우스를 아래로 끌어서 마우스로 강조 표시 한 텍스트 만 선택해야합니다.
  3. 텍스트 상자에 이미 초점이 맞춰져 있으면 클릭해도 모든 텍스트가 선택되지는 않습니다.
  4. 프로그래밍 방식으로 또는 키보드 탭을 통해 텍스트 상자에 초점을 맞추면 모든 텍스트를 선택해야합니다.

WinForms에서 정확히 이것을하고 싶습니다.

가장 빠른 총 경고 : 응답하기 전에 다음을 읽으십시오! 고마워 🙂

.Enter 또는 .GotFocus 이벤트 중에 .SelectAll ()을 호출 하면 사용자가 텍스트 상자를 클릭 한 경우 캐럿이 클릭 한 위치에 캐럿이 배치되어 모든 텍스트가 선택 취소되므로 작동하지 않습니다 .

사용자가 마우스로 텍스트를 선택할 수 없기 때문에 .Click 이벤트 중에 .SelectAll ()을 호출하면 작동 하지 않습니다. .SelectAll () 호출은 사용자의 텍스트 선택을 덮어 씁니다.

포커스 / 엔터 이벤트 입력시 BeginInvoke ((Action) textbox.SelectAll)을 호출 하면 위의 규칙 # 2가 위반되어 작동하지 않습니다 . 포커스에서 사용자의 선택을 계속 무시합니다.



답변

우선, 답변 주셔서 감사합니다! 총 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();
    }
}

내가 알 수있는 한, 이것은 텍스트 상자가 웹 브라우저의 주소 표시 줄과 똑같이 동작하게합니다.

잘만되면 이것은이 믿을 수 없을 정도로 간단한 문제를 해결하려는 다음 사람에게 도움이되기를 바랍니다.

올바른 길로 인도하는 데 도움이 된 모든 답변에 대해 다시 한 번 감사드립니다.


답변

더 간단한 해결책을 찾았습니다. Control.BeginInvokeEnter 및 Click 이벤트가 발생한 후에 발생하도록 SelectAll을 비동기 적으로 사용하여 시작합니다.

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


답변

귀하의 솔루션은 좋지만 특정 사례에서 실패합니다. 그냥 클릭하는 대신 텍스트 범위를 선택하여 TextBox 포커스를 설정하면 이미 초점 플래그가 true로 설정되지 않으므로 TextBox를 두 번 클릭하면 모든 텍스트가 선택됩니다.

여기 내 솔루션 버전이 있습니다. 또한 TextBox를 상속하는 클래스에 코드를 넣었으므로 논리가 숨겨져 있습니다.

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


답변

약간 엉뚱하지만 클릭 이벤트에서는을 사용하십시오 SendKeys.Send( "{HOME}+{END}" );.


답변

텍스트 상자의 이벤트를 클릭 하시겠습니까? 또는 MouseCaptureChanged 이벤트조차도 나를 위해 작동합니다. – 확인. 작동하지 않습니다.

따라서 두 가지 작업을 수행해야합니다.

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

텍스트 상자를 통해 탭으로도 사용할 수 있습니다-경우에 따라 Enter에서 SelectAll ()을 호출하십시오 …


답변

내가 사용하는 한 줄의 대답 … 당신은 스스로 발로 차고있을 수 있습니다 …

엔터 이벤트에서 :

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


답변

'Inside the Enter event
TextBox1.SelectAll();

좋아, 여기에 시도한 후에는 원하는 것입니다.

  • Enter 이벤트에서 Enter 이벤트에 있었음을 나타내는 플래그를 시작하십시오.
  • Click 이벤트에서 플래그를 설정 한 경우 .SelectAll ()을 호출하고 플래그를 재설정하십시오.
  • MouseMove 이벤트에서 입력 한 플래그를 false로 설정하면 텍스트 상자를 먼저 입력하지 않고도 강조 표시를 클릭 할 수 있습니다.

입력시 모든 텍스트를 선택했지만 나중에 텍스트의 일부를 강조 표시하거나 처음 클릭 할 때 강조 표시 할 수있었습니다.

요청에 의해:

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

나를 위해 컨트롤을 누르면 모든 텍스트가 선택됩니다.