Заставить WinForms TextBox вести себя как адресная строка вашего браузера - PullRequest
149 голосов
/ 19 сентября 2008

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

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

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

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

Предупреждение о быстром огнестрельном оружии: пожалуйста, прочитайте следующее, прежде чем ответить! Спасибо, ребята. : -)

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

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

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

Ответы [ 31 ]

1 голос
/ 03 мая 2012

SelectAll у меня никогда не работал.

Это работает.

ActiveControl = textBox1;
textBox1->SelectionStart = 0;
textBox1->SelectionLength = textBox1->Text->Length;
1 голос
/ 01 декабря 2014

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

Чтобы убедиться, что весь текст выделен при нажатии на текстовое поле, убедитесь, что обработчик 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();
    }
0 голосов
/ 31 августа 2012

Следующее решение работает для меня. Я добавил переопределение событий 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;
    }
}
0 голосов
/ 13 января 2012

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

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

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

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

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

0 голосов
/ 22 декабря 2008

Вы пробовали решение, предложенное на форуме MSDN "Windows Forms General" , которое просто подклассов TextBox?

0 голосов
/ 23 сентября 2014

Очень простое решение:

    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 голосов
/ 19 сентября 2008
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();
    }
}
0 голосов
/ 19 июля 2015

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

private async void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (sender is TextBox)
    {
        await Task.Delay(100);
        (sender as TextBox).SelectAll();
    }
}
0 голосов
/ 15 апреля 2010

Я создал новый проект 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
0 голосов
/ 06 января 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...