TextBox
다음과 같이 문자열로 설정 한 C #에서를 포함하는 양식이 있습니다.
textBox.Text = str;
양식이 표시 될 때 texbox의 텍스트가 강조 표시 / 선택된 이유는 무엇입니까?
TextBox
다음과 같이 문자열로 설정 한 C #에서를 포함하는 양식이 있습니다.
textBox.Text = str;
양식이 표시 될 때 texbox의 텍스트가 강조 표시 / 선택된 이유는 무엇입니까?
답변:
텍스트 상자는 TabIndex
0이고 TabStop
true로 설정됩니다. 이것은 폼이 표시 될 때 컨트롤에 포커스가 주어짐을 의미합니다.
다른 컨트롤에 0 TabIndex
(있는 경우)을 지정하고 텍스트 상자에 다른 탭 인덱스 (> 0)를 지정하거나 TabStop
텍스트 상자에 대해 false로 설정 하여이 문제가 발생하지 않도록 할 수 있습니다.
Windows Forms에서 TextBox의 기본 동작은 처음으로 탭하여 포커스를 받으면 모든 텍스트를 강조 표시하지만 클릭 한 경우에는 강조 표시하지 않는 것입니다. Reflector에서 TextBox
의 OnGotFocus()
오버라이드를 보면 이것을 볼 수 있습니다.
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()
그냥 SelectionLength
0으로 설정 합니다. 실제로 의 변수 SelectionStart
를 뒤집습니다 . 위의 경우 시작을 텍스트의 끝으로 설정하므로 to 호출 이 필요하지 않습니다.하지만 다른 위치로 설정하면 텍스트의 시작 부분을 호출 한 다음 호출하는 것이 좋습니다.)TextBox
selectionSet
DeselectAll()
보다 영구적 인 방법은 상속을 통해 원하는 동작으로 자체 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. 그러나 그것이 무엇인지입니다.
다음을 열어 양식 컨트롤의 탭 순서를 선택할 수도 있습니다.
보기-> 탭 순서
이 옵션은 양식 디자인보기가 열려있는 경우 "보기"에서만 사용할 수 있습니다.
"탭 순서"를 선택하면 컨트롤을 클릭하여 원하는 탭 순서를 선택할 수있는 양식보기가 열립니다.
텍스트 필드의 강조 표시를 해제하려면 VS 2013에서 다음을 사용하여 init를 시도하십시오.
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
그리고 방법을 추가하십시오.
public void myTextBox_GotFocus(object sender, EventArgs e)
{
myTextBox.SelectionLength=0;
}
나는 이것을 C #에서 테스트하지 않았지만 C ++ WIN32 대화 상자를 사용하여 동일한 문제가 발생했습니다. 또는 FALSE
에서 돌아와서 동작을 변경할 수있는 것 같습니다 . 도움이 되었기를 바랍니다.OnInitDialog()
WM_INITDIALOG