양식이 표시 될 때 TextBox의 텍스트가 강조 표시 (선택)되는 이유는 무엇입니까?


84

TextBox다음과 같이 문자열로 설정 한 C #에서를 포함하는 양식이 있습니다.

textBox.Text = str;

양식이 표시 될 때 texbox의 텍스트가 강조 표시 / 선택된 이유는 무엇입니까?



이 문제를 해결 했습니까? 어떻게 고쳤나요?
플레처

@fletcher : 나는 아직 그것을 보지 못했습니다. 며칠 안에 답변을 드리겠습니다.
CJ7

문제이기 때문에 당신은 정말 같은 허용 된 대답은 너무 유효하는 vb.net 태그를 추가 할 수 있습니다
안드레아 Antonangeli

탭 순서보기와 관련된 BenSmith의 답변은 이러한 시나리오에서 매우 유용 할 것입니다.
Samitha Chathuranga 2015

답변:


128

텍스트 상자는 TabIndex0이고 TabStoptrue로 설정됩니다. 이것은 폼이 표시 될 때 컨트롤에 포커스가 주어짐을 의미합니다.

다른 컨트롤에 0 TabIndex(있는 경우)을 지정하고 텍스트 상자에 다른 탭 인덱스 (> 0)를 지정하거나 TabStop텍스트 상자에 대해 false로 설정 하여이 문제가 발생하지 않도록 할 수 있습니다.


1
텍스트 상자 TabIndex가 0으로 설정되어 있습니까? 그 행동에서 나온다?
26071986

@ 26071986-음, 빠른 테스트를 실행했습니다. 하나의 텍스트 상자와 단추가있는 양식에서 tabindex가 0으로 설정되어있을 때 생성자의 텍스트 상자 내의 텍스트를 변경하면 텍스트가 강조 표시됩니다. 버튼에 0 탭 인덱스가 있고 텍스트 상자 tabindex가> 0이면 텍스트가 강조 표시되지 않습니다.
플레처

실제로 TabIndex와 관련된 것 같습니다. 모든 요소 탭 인덱스를 적절하게 변경했습니다 (그래서 생각했습니다). 그룹에는 모든 포함 요소뿐만 아니라 변경해야하는 탭 인덱스도 있습니다. 따라서 1-9에서 요소 탭을 설정하는 동안 그룹에는 여전히 0이 있으므로 해당 그룹의 텍스트 상자가 첫 번째 활성화 된 요소가되었습니다 (따라서 해당 내용이 강조 표시됨).
deed02392 2013 년

1
TabIndex = 0을 갖는 것과 반드시 ​​관련이있는 것은 아니지만 TextBox에 양식의 LOWEST TabIndex가 있으면 확실히 발생합니다. 확인하려면 : TextBox에서 TabIndex = 5를 설정하고 양식에있는 다른 컨트롤의 모든 TabIndex에서 5보다 큰 숫자를 설정합니다.
Andrea Antonangeli

이것은 TabControl에서 새 TabPage를 선택할 때도 발생합니다. 동일한 솔루션이 작동합니다.
JonP

43

Windows Forms에서 TextBox의 기본 동작은 처음으로 탭하여 포커스를 받으면 모든 텍스트를 강조 표시하지만 클릭 한 경우에는 강조 표시하지 않는 것입니다. Reflector에서 TextBoxOnGotFocus()오버라이드를 보면 이것을 볼 수 있습니다.

protected override void OnGotFocus(EventArgs e)
{
    base.OnGotFocus(e);
    if (!this.selectionSet)
    {
        this.selectionSet = true;
        if ((this.SelectionLength == 0) && (Control.MouseButtons == MouseButtons.None))
        {
            base.SelectAll();
        }
    }
}

우리가 좋아하지 않는 행동을 일으키는 if 문입니다. 또한 부상에 대한 모욕을 추가하기 위해 Text속성의 세터 selectionSet는 텍스트가 다시 할당 될 때마다 해당 변수를 맹목적으로 재설정합니다 .

public override string Text
{
    get
    {
        return base.Text;
    }
    set
    {
        base.Text = value;
        this.selectionSet = false;
    }
}

따라서 TextBox와 탭이 있으면 모든 텍스트가 선택됩니다. 클릭하면 강조 표시가 제거되고 다시 탭하면 캐럿 위치 (및 선택 길이 0)가 유지됩니다. 그러나 프로그래밍 방식으로 new를 설정 Text하고 다시 TextBox에 탭하면 모든 텍스트가 다시 선택됩니다.

당신이 나와 같고이 행동이 성 가시고 일관성이 없다고 생각한다면,이 문제를 해결하는 두 가지 방법이 있습니다.

첫 번째이자 아마도 가장 쉬운 방법은 양식 selectionSet을 호출 하고 변경 될 때마다 설정을 트리거하는 것입니다 .DeselectAll()Load()Text

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    this.textBox2.SelectionStart = this.textBox2.Text.Length;
    this.textBox2.DeselectAll();
}

( DeselectAll()그냥 SelectionLength0으로 설정 합니다. 실제로 의 변수 SelectionStart를 뒤집습니다 . 위의 경우 시작을 텍스트의 끝으로 설정하므로 to 호출 이 필요하지 않습니다.하지만 다른 위치로 설정하면 텍스트의 시작 부분을 호출 한 다음 호출하는 것이 좋습니다.)TextBoxselectionSetDeselectAll()

보다 영구적 인 방법은 상속을 통해 원하는 동작으로 자체 TextBox를 만드는 것입니다.

public class NonSelectingTextBox : TextBox
{
    // Base class has a selectionSet property, but its private.
    // We need to shadow with our own variable. If true, this means
    // "don't mess with the selection, the user did it."
    private bool selectionSet;

    protected override void OnGotFocus(EventArgs e)
    {
        bool needToDeselect = false;

        // We don't want to avoid calling the base implementation
        // completely. We mirror the logic that we are trying to avoid;
        // if the base implementation will select all of the text, we
        // set a boolean.
        if (!this.selectionSet)
        {
            this.selectionSet = true;

            if ((this.SelectionLength == 0) && 
                (Control.MouseButtons == MouseButtons.None))
            {
                needToDeselect = true;
            }
        }

        // Call the base implementation
        base.OnGotFocus(e);

        // Did we notice that the text was selected automatically? Let's
        // de-select it and put the caret at the end.
        if (needToDeselect)
        {
            this.SelectionStart = this.Text.Length;
            this.DeselectAll();
        }
    }

    public override string Text
    {
        get
        {
            return base.Text;
        }
        set
        {
            base.Text = value;

            // Update our copy of the variable since the
            // base implementation will have flipped its back.
            this.selectionSet = false;
        }
    }
}

을 호출하지 않고 base.OnGotFocus()싶을 수도 있지만 기본 Control클래스 에서 유용한 기능을 잃게됩니다 . 그리고 당신은 selectionSet말도 안되는 것을 전혀 엉망으로 만들지 않고 OnGotFocus ()에서 매번 텍스트를 선택 취소하고 싶을 수도 있지만, 필드에서 탭을하여 뒤로 이동하면 사용자의 강조 표시를 잃게됩니다.

추한? 당신은 betcha. 그러나 그것이 무엇인지입니다.


31

이 질문에 대한 답변은 비슷한 문제로 많은 도움이되었지만 간단한 답변은 다른 많은 복잡한 제안에서만 암시됩니다. 그냥 설정 SelectionStart0텍스트를 설정 한 후. 문제 해결됨!

예:

yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;

4

다음을 열어 양식 컨트롤의 탭 순서를 선택할 수도 있습니다.

보기-> 탭 순서

이 옵션은 양식 디자인보기가 열려있는 경우 "보기"에서만 사용할 수 있습니다.

"탭 순서"를 선택하면 컨트롤을 클릭하여 원하는 탭 순서를 선택할 수있는 양식보기가 열립니다.


1
이것은 나를 많이 도왔다. 실제로 탭 순서에 관심이 있다면 탭 인덱스는 중요하지 않습니다.
Samitha Chathuranga 2015

1

텍스트 필드의 강조 표시를 해제하려면 VS 2013에서 다음을 사용하여 init를 시도하십시오.

myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);

그리고 방법을 추가하십시오.

public void myTextBox_GotFocus(object sender, EventArgs e)
{
    myTextBox.SelectionLength=0;
}

이로 인해 이전에 텍스트 상자에 초점을 맞추고 그 안에있는 일부 텍스트를 선택한 후 다른 곳으로 이동 한 다음 다시 초점을 맞춘 경우 텍스트가 선택 해제됩니다.
Stewart

0

나는 이것을 C #에서 테스트하지 않았지만 C ++ WIN32 대화 상자를 사용하여 동일한 문제가 발생했습니다. 또는 FALSE에서 돌아와서 동작을 변경할 수있는 것 같습니다 . 도움이 되었기를 바랍니다.OnInitDialog()WM_INITDIALOG


1
Windows API가 winforms 내부에 캡슐화되어 있기 때문에 이것이 많이 도움이 될 것이라고 생각하지 않습니다.
Nathan A
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.