У меня есть форма, содержащая текстовое поле в С#, которое я задал для строки следующим образом:
textBox.Text = str;
Когда отображается форма, почему текст в texbox отображается выделенным/выбранным?
У меня есть форма, содержащая текстовое поле в С#, которое я задал для строки следующим образом:
textBox.Text = str;
Когда отображается форма, почему текст в texbox отображается выделенным/выбранным?
Текстовое поле имеет TabIndex от 0 и TabStop, установленное в значение true. Это означает, что элемент управления будет фокусироваться при отображении формы.
Вы можете либо дать другому элементу управления 0 TabIndex (если он есть), и дать текстовому полю другой указатель вкладки ( > 0), либо установить TabStop на false для текстового поля, чтобы это не происходило.
Поведение TextBox по умолчанию в Windows Forms по умолчанию заключается в том, чтобы выделить весь текст, если он будет сфокусирован в первый раз, введя в него вкладку, но не при нажатии на него. Мы можем увидеть это в Reflector, посмотрев на TextBox OnGotFocus() override:
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 и вкладка в него, будет выбран весь текст. Если вы нажмете на него, выделение будет удалено, и если вы заново вложите его в него, ваша позиция каретки (и длина выделения равна нулю) будет сохранена. Но если мы программным образом добавим новый 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, который переворачивает переменную 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(), но тогда мы потеряем подсветку пользователя, если они будут выведены из поля и обратно.
Гадкий? Еще бы. Но это то, что есть.
Ответы на этот вопрос помогли мне с подобной проблемой, но простой ответ намечен только на множество других сложных предложений. Просто установите SelectionStart на 0 после настройки текста. Проблема решена!
Пример:
yourtextbox.Text = "asdf";
yourtextbox.SelectionStart = 0;
		Вы также можете выбрать порядок вкладок для элементов управления формы, открыв:
View- > Tab Order
Обратите внимание, что этот параметр доступен только в "Вид", если у вас открыто представление формы.
Выбор "Tab Order" открывает вид формы, который позволяет вам выбрать желаемый порядок вкладок, щелкнув элементы управления.
Чтобы высвечивать текстовое поле с VS 2013, попробуйте выполнить init с помощью
myTextBox.GotFocus += new System.EventHandler(this.myTextBox_GotFocus);
И добавьте метод:
public void myTextBox_GotFocus(object sender, EventArgs e)
{
    myTextBox.SelectionLength=0;
}
		Я не тестировал это на С#, но я столкнулся с той же проблемой, используя диалоговое окно С++ WIN32. Похоже, вы можете изменить поведение, вернув FALSE из OnInitDialog() или WM_INITDIALOG. Надеюсь, это поможет.