Заставить WinForms TextBox вести себя как адресная строка вашего браузера

154

Когда текстовое поле C # WinForms получает фокус, я хочу, чтобы оно велось как адресная строка вашего браузера.

Чтобы понять, что я имею в виду, нажмите в адресной строке вашего браузера. Вы заметите следующее поведение:

  1. Нажатие в текстовом поле должно выделить весь текст, если текстовое поле не было предварительно сфокусировано.
  2. Мышь вниз и перетаскивание в текстовое поле должны выбрать только текст, который я выделил мышью.
  3. Если текстовое поле уже выделено, нажатие не выделяет весь текст.
  4. Фокусировка текстового поля программно или с помощью клавиатуры должна выделять весь текст.

Я хочу сделать именно это в WinForms.

САМОЕ БЫСТРОЕ ПРЕДУПРЕЖДЕНИЕ: пожалуйста, прочитайте следующее, прежде чем ответить! Спасибо, парни. :-)

Вызов .SelectAll () во время событий .Enter или .GotFocus не будет работать, потому что, если пользователь щелкнул текстовое поле, курсор будет размещен там, где он щелкнул, тем самым отменив выделение всего текста.

Вызов .SelectAll () во время события .Click не будет работать, потому что пользователь не сможет выделить текст мышью; вызов .SelectAll () будет перезаписывать выделение текста пользователем.

Вызов BeginInvoke ((Action) textbox.SelectAll) при вводе события focus / enter не работает, поскольку он нарушает правило № 2, приведенное выше, он будет переопределять выбор пользователя в фокусе.

Иуда Габриэль Химанго
источник
3
Пожалуйста, уточните это для "RichTextBox".
Nescio
Nescio, текстовое поле или расширенное текстовое поле подойдет. Я пробовал ваше решение в текстовом поле тоже.
Иуда Габриэль Химанго
Это утечка абстракции. Лучший способ сделать это - пометить WM_MOUSEACTIVATE и SelectAll на WM_SETFOCUS, если не WM_MOUSEACTIVATE-ing.
wqw
Версия WPF: stackoverflow.com/questions/4161531/…
Джонатан Аллен

Ответы:

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

Насколько я могу судить, это приводит к тому, что текстовое поле ведет себя точно так же, как адресная строка веб-браузера.

Надеюсь, это поможет следующему парню, который пытается решить эту обманчиво простую проблему.

Еще раз спасибо, ребята, за все ваши ответы, которые помогли привести меня к правильному пути.

Иуда Габриэль Химанго
источник
Как насчет того, когда фокус программно установлен на TextBox? У меня есть эта проблема, как обсуждалось здесь: stackoverflow.com/questions/24790704/… Я смог решить ее по-своему, но я все еще волнуюсь по этому поводу, так как мое «исправление» кажется довольно глупым.
Б. Клэй Шеннон
Вы написали: «Вызов .SelectAll () во время событий .Enter или .GotFocus не будет работать, потому что, если пользователь щелкнул текстовое поле, курсор будет размещен там, где он щелкнул, тем самым отменив выбор всего текста». У меня есть SelectAll в событии GotFocus, которое, по большей части, работает. На самом деле, я думаю, что курсор, размещенный там, где щелкнул пользователь, - это «хорошо». Я просто хочу, чтобы он всегда был выбран, когда фокус установлен на TextBox программно.
Б. Клэй Шеннон
И я снова здесь! :)
dotNET
3
Вы должны переместить alreadyFocused = true;in MouseUp из оператора if. Потому что, если вы сразу выделите части текста, следующий щелчок снова выделит весь текст.
Роберт С.
Ниже приведен однострочный ответ --- 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 (спасибо Кришану Дей )

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 не работает для меня (несомненно, из-за моей катастрофически пыльной версии Dot net). Предшествующий "Контроль". это не помогает, равно как и добавление имени самого TextBox. Один и бледно слоняется ...
Б. Клэй Шеннон
2
Обратите внимание, что это решение не ведет себя точно так, как описано в вопросе. Специально Mouse down and drag in the textbox should select only the text I've highlighted with the mouse.не работает, как хотелось бы. Но все же самое короткое и элегантное решение :)
Маркус Мангельсдорф,
30

Ваше решение хорошо, но не в одном конкретном случае. Если вы фокусируете TextBox, выбирая диапазон текста, а не просто щелкаете мышью, для флага Уже Фокусировано не устанавливается значение true, поэтому при повторном щелчке в текстовом поле весь текст выделяется.

Вот моя версия решения. Я также поместил код в класс, который наследует 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;
        }
    }
}
nzhenry
источник
2
+1 для пользовательского предложения текстового поля и отлично работающего решения!
Fueled
Потрясающее решение. Скопировал ваш код прямо в мое решение, изменил пространство имен, чтобы защитить невинных, и работал отлично. Спасибо!
kenswdev
8

Это немного хитро, но в вашем событии клика, используйте SendKeys.Send( "{HOME}+{END}" );.

Тодд беннинг
источник
Woofta! Это немного хакерства! :-) Спасибо за предложение. Есть идеи получше?
Иуда Габриэль Химанго
Взлом действительно, но это совсем не плохо
Терри
3
Учтите, что многие антивирусные программы перехватывают и блокируют SEND KEYS как вредоносные. Это не отличное решение.
Иуда Габриэль Химанго
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; 
}

Работает и для табуляции (через textBoxes к одному) - вызовите SelectAll () в Enter на всякий случай ...

Якуб Котрла
источник
Хорошо, Якуб, это частично работает. Если я вкладываю текстовое поле, оно должно быть сфокусировано. Будет ли это работать с вашим решением? (Если вы можете показать мне, как, я
отмечу
Якуб, теперь, когда ты выложил код, кажется, он иногда работает. Не всегда; сейчас я щелкаю в текстовое поле, и он не выбирает все.
Иуда Габриэль Химанго
Иногда я нажимаю на текст, и он не выделяет все. Как будто в поле .f не установлено то, что должно быть, а затем SelectAll не вызывается. Не видел этого?
Иуда Габриэль Химанго
Я знаю только то, что из-за mouseMouve вы можете медленно щелкнуть при перемещении мыши (особенно по широким буквам) -> снять флажок. Вы можете удалить код в событии mouseMove, но затем вы получаете - после tabbgin для управления и последующего нажатия - reSelectAll - невозможно выбрать часть перемешивания при первом перетаскивании
Jakub Kotrla
4

Ответ в одну строку, который я использую ... вы можете пнуть себя ...

В событии Enter:

txtFilter.BeginInvoke (новый MethodInvoker (txtFilter.SelectAll));


источник
1
Нет, не работает. Хорошо, он выделяет весь текст, но он также не позволяет пользователю выбирать только часть текста, среди других проблем.
Иуда Габриэль Химанго
Извините, я, наверное, неправильно понял поведение, которое вы искали. При вводе он выбирает все, если щелкнуть и удерживать его, выберите от начала до курсора. Я полагаю, вы могли бы использовать то, что у меня есть, и заменить SelectAll своей собственной логикой выбора. notifywire.com/demos/2009-04-14_1248.swf
Прекрасно работает! Первый щелчок входит в поле; затем нажмите и перетащите, чтобы выделить текст.
D_Bester
Примечание: он не работает как адресная строка веб-браузера. Адресная строка веб-браузера позволяет вам щелкать мышью в текстовом поле и перетаскивать / выбирать, даже если текстовое поле еще не сфокусировано. Это решение не решает это. Если вы согласны с этим, круто, но это не удовлетворяет требованиям этого вопроса.
Иуда Габриэль Химанго,
3
'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;
    }

Для меня вкладка в элемент управления выделяет весь текст.

MagicKat
источник
Ваше решение похоже на решение Якуба. Это работает для нажатия. Может ли это работать при вставке в текстовое поле? (Например, вкладка в адресную строку вашего браузера также выделит весь текст.)
Иуда Габриэль Химанго
Да, это работает и для табуляции. Я написал тестовое приложение, и именно так оно и заработало.
MagicKat
Кажется, не работает для табуляции. Можете ли вы показать нам код, который работает для табуляции?
Иуда Габриэль Химанго
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();
            }   
        });
    }

Чтобы использовать это, просто вызовите функцию, передающую TextBox, и она позаботится обо всех ваших проблемах. Я предлагаю подключить все ваши текстовые поля в событии 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 , но мне легче не иметь подкласса:

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;
Адам Брусс
источник
Это не учитывает случай, когда вкладка в текстовое поле приносит фокус. Он также демонстрирует некоторые другие проблемы, обсуждаемые в этой теме.
Иуда Габриэль Химанго
1

Я нашел еще более простое решение:

Чтобы убедиться, что весь текст выделен при нажатии на текстовое поле, убедитесь, что обработчик Click вызывает обработчик Enter. Нет необходимости в дополнительных переменных!

Пример:

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();
    }
Питер Хемерик
источник
Это не работает для фокуса через вкладки в элементе управления, верно? Кроме того, что делать, когда вы хотите выделить какой-то текст, не выделив все?
Иуда Габриэль Химанго
На самом деле, он работает с вкладками в него! Я только что проверил это в фиктивном проекте, использующем MS Visual C # 2010. Раздражающая вещь с этим решением - то, что вы не можете выделить некоторый текст, не выделив все. Если вы хотите сделать это, конечно, код не нужен, вы можете просто использовать мышь и выбрать ее (или с помощью клавиатуры).
Питер Хемерик
И именно поэтому это решение не решает представленную проблему: оно не ведет себя как адресная строка браузера, потому что вы не можете щелкнуть отдельные части адреса, не выбрав весь текст.
Иуда Габриэль Химанго
Хорошо, я понимаю, что вы имеете в виду. Название вопроса и пример адресной строки веб-браузера не указывали на то, что вы должны быть в состоянии выделить какую-то часть текста. Вы упомянули об этом только как сторону в последнем предложении вашего вопроса. С уважением.
Питер Хемерик,
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();
    }
}
Nescio
источник
Я только что протестировал с RichTextBox. Не работает Нажатие на текстовое поле не появляется, чтобы выделить весь текст. (Потому что он отменяется при наведении мыши, когда курсор помещается на курсор.)
Иуда Габриэль Химанго,
0

Интересно, что ComboBox с DropDownStyle = Simple имеет в точности то поведение, которое вы ищете, я думаю.

(Если вы уменьшите высоту элемента управления, чтобы список не отображался, а затем еще на пару пикселей, эффективная разница между ComboBox и TextBox отсутствует).


источник
Интересно, но мне действительно нужно это для работы с TextBox и RichTextBox.
Иуда Габриэль Химанго
0

Почему бы вам просто не использовать MouseDown-Event текстового поля? Он прекрасно работает для меня и не требует дополнительного логического значения. Очень чисто и просто, например:

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

источник
Нет, пара проблем с этим: не учитывает, если текстовое поле уже имеет фокус (мы не хотим выделять все мышью вниз, только когда текстовое поле не имеет фокус), не позволяет вам просто выбрать часть текста, не работает, когда фокус переносится с помощью вкладок в текстовое поле.
Иуда Габриэль Химанго
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);
    }
Сриджит К.
источник
Да, посмотрите другие ответы (и комментарии), почему это не работает во всех сценариях.
Иуда Габриэль Химанго
Я не проверял вкладку для этого решения. Виноват. Спасибо за указание. Рад видеть, что у вас есть полное решение сейчас. А также рад узнать, что мое предложение для MouseUp было включено в ваше решение.
Сриджит К.
0

Просто выведите класс из TextBox или MaskedTextBox:

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

И используйте это на своих формах.

Мухаммед Махдипур
источник
Это не работает Чтобы понять почему, смотрите другие ответы и комментарии.
Иуда Габриэль Химанго
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 секунды.
Иуда Габриэль Химанго
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;   
}
Yfiua
источник
1
Это не работает должным образом; см. мои ответы на другие ответы, которые предлагают .SelectAll (). Это не работает, потому что, если вы вводите текстовое поле при попытке выделить текст, оно нарушает ваш выбор текста, выделяя весь текст. Вы хотите выделить текст только в том случае, если фокус вводится в текстовое поле с помощью мыши вверх или вкладок, но если фокус был вызван с помощью мыши вниз.
Иуда Габриэль Химанго
0

Я знаю, что это уже было решено, но у меня есть предположение, которое я считаю довольно простым.

В событии мыши вверх все, что вам нужно сделать, это поместить

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

Кажется, это работает для меня в VB.NET (я знаю, что это вопрос C # ... к сожалению, я вынужден использовать VB на своей работе ... и у меня была эта проблема, которая привела меня сюда ... )

Я не нашел никаких проблем с этим .. за исключением того факта, что он не сразу выбирается при нажатии, но у меня были проблемы с этим ....

Eluem
источник
1
Исходный запрос хотел, чтобы это работало, когда вы вкладываете в поле также.
Дон Киркби
2
Да, это не работает для всех сценариев. Работает только при нажатии в текстовое поле. И даже тогда, если не ведет себя как адресная строка браузера ведет себя, когда выделение уже существует в текстовом поле.
Иуда Габриэль Химанго
0

Следующее решение работает для меня. Я добавил OnKeyDownи OnKeyUpпереопределение событий, чтобы текст TextBox оставался всегда выделенным.

    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;
    }
}
abrfra
источник
2
Позволяет ли вам навести курсор мыши на текстовое поле, перетащить курсор, чтобы выделить текст, а затем навести курсор вверх?
Иуда Габриэль Химанго
0

Установите выбор, когда вы покидаете контроль. Это будет там, когда ты вернешься. Нажмите на форму, и когда вы вернетесь к элементу управления, будет выделен весь текст.

Если вы нажмете мышкой, то каретка будет правильно размещена в том месте, где вы щелкнули.

private void maskedTextBox1_Leave(object sender, CancelEventArgs e)
    {
        maskedTextBox1.SelectAll();
    }
Joel
источник
Если вы заходите мышкой, он должен выделить весь текст, если он уже не сфокусирован. Это не поддерживает это.
Иуда Габриэль Химанго
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 );
    }

* На самом деле следующая последовательность заканчивается частичным выделением текста, но затем, если вы наведете курсор мыши на текстовое поле, весь текст будет выделен снова:

мышь-вниз / выделение текста / мышь-перемещение-текстовое поле / мышь-вверх

Мауро Сампьетро
источник
Это решение уже было опубликовано. Посмотрите комментарий к существующему ответу, чтобы узнать, почему он не работает.
Иуда Габриэль Химанго,
работает с вкладкой и с мышью, вы можете получить фокус, выделите текст, а затем мышь вверх. Я не могу найти проблему с этим. Можете ли вы указать на это?
Мауро Сампьетро
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;
    }
user3729779
источник
0

Мое решение довольно примитивно, но отлично работает для моих целей

private async void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (sender is TextBox)
    {
        await Task.Delay(100);
        (sender as TextBox).SelectAll();
    }
}
BlueWizard
источник
Не работает, если вы хотите навести курсор мыши вниз, чтобы выделить текст, перетащите мышку, а затем наведите курсор мыши вверх. Ваш код очистит выбор и выберет все.
Иуда Габриэль Химанго
@JudahHimango Jup. Если вы нажмете один раз, он выберет все. Если вы нажмете и перетащите, он выберет только выбор. По крайней мере, панель браузера в Firefox показывает именно такое поведение.
BlueWizard
разве это не состояние гонки? Если мне удастся быстро выделить текст с помощью мыши, то .SelectAll () будет срабатывать через миллисекунды, перезаписывая мой выбор.
Джуда Габриэль Химанго
1
Хорошо, если вы быстро выбираете вещи, то эта вещь будет работать против вас.
BlueWizard,
-1

Ниже, кажется, работает. Событие enter обрабатывает вкладки для элемента управления, а MouseDown работает при нажатии на элемент управления.

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

    private void textBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (textBox1.Focused)
            textBox1.SelectAll();
    }
benPearce
источник
Не повезло, не работает, боюсь. Попробуйте выбрать текст. Текст .SelectAll перезаписывает то, что пытается выбрать пользователь.
Иуда Габриэль Химанго
-1

Ответ может быть на самом деле более простым, чем ВСЕ из вышеперечисленного, например (в WPF):

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

конечно, я не могу знать, как вы хотите использовать этот код, но основная часть, на которую стоит обратить внимание, это: сначала вызов .Focus (), а затем вызов .SelectAll ();

MDB
источник
Это не работает, и является дубликатом других ответов. Например, если вы щелкаете мышью в текстовом поле, перетаскиваете, он должен выделить часть текста. Это ломает это и не выбирает все.
Иуда Габриэль Химанго
-1

просто используйте selectall () при вводе и клике по событиям

private void textBox1_Enter(object sender, EventArgs e)
        {

            textBox1.SelectAll();
        }
        private void textBox1_Click(object sender, EventArgs e)
        {
            textBox1.SelectAll();
        }
EKanadily
источник
Это работает, пока вы не хотите выделить текст. Смотрите другие ответы для полного объяснения.
Иуда Габриэль Химанго
-1

Я создал новый проект VB.Net Wpf. Я создал один TextBox и использовал следующее для codebehind:

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
BSalita
источник