Disable selecting text in a TextBox

2020-02-01 08:24发布

问题:

I have a textbox with the following (important) properties:

this.license.Multiline = true;
this.license.ReadOnly = true;
this.license.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.license.ShortcutsEnabled = false;

It looks like this:

How can I disable the user to highlight text in this textbox (I do not want to disable the textbox completely)?

回答1:

Attach to the SelectionChanged event, and inside the event set e.Handled = true; and the SelectionLength = 0; and that will stop the selection from occuring. This is similar to what it takes to keep a key press from happening.



回答2:

If you put the text into a label and then but the label into a System.Widnows.Forms.Panel control that has AutoScroll turned on you can display the text w/o it being selectable.



回答3:

To disable selection highlight in a TextBox, you can override WndProc and handle WM_SETFOCUS message and replace it with a WM_KILLFOCUS. Please be aware that it doesn't make the TextBox control read-only and if you need to make it read-only, you should also set ReadOnly property to true. If you set ReadOnly to true, you can set and its BackColor to White or any other suitable color which you want.

In below code, I added a SelectionHighlightEnabled property to MyTextBox to make enabling or disabling the selection highlight easy:

  • SelectionHighlightEnabled: Gets or sets a value indicating selection highlight is enabled or not. The value is true by default to act like a normal TextBox. If you set it to false then the selection highlight will not be rendered.
using System.ComponentModel;
using System.Windows.Forms;
public class MyTextBox : TextBox
{
    public MyTextBox()
    {
        SelectionHighlightEnabled = true;
    }
    const int WM_SETFOCUS = 0x0007;
    const int WM_KILLFOCUS = 0x0008;
    [DefaultValue(true)]
    public bool SelectionHighlightEnabled { get; set; }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_SETFOCUS && !SelectionHighlightEnabled)
            m.Msg = WM_KILLFOCUS;

        base.WndProc(ref m);
    }
}


回答4:

If you are using XAML / WPF you should use a TextBlock instead of a TextBox.

ONLY IF YOU USE A TEXTBOX AS A DISPLAY AND NOT FOR INPUT - as TextBlock makes it seem as if the text is "engraved" onto the form itself, and not within a textbox. To get a Border around the TextBlock (if you wish), you can either do it :

In XAML such as :

<Border BorderThickness="1" BorderBrush="Gray">
    <TextBlock Background="White" Text="Your Own TextBlock"/>
</Border>

Or dynamically in C# Code:

//Create a Border object
Border border = new Border();
border.BorderThickness = new Thickness(1);
border.BorderBrush = Brushes.Black;

//Create the TextBlock object           
TextBlock tb = new TextBlock();
tb.Background = Brushes.White;
tb.Text = "Your Own TextBlock";

//Make the text block a child to the border
border.Child = tb;


回答5:

You can use a disabled RichTextBox and reset the color to black afterwards.

RichTextBox rtb = new RichTextBox();
rtb.IsEnabled = false;
rtb.Text = "something";
rtb.SelectAll();
rtb.SelectionColor = Color.Black;
rtb.SelectedText = String.Empty;


回答6:

Since the standard TextBox doesn't have the SelectionChanged event, here's what I came up with.

private void TextBox1_MouseMove(object sender, MouseEventArgs e)
{
    TextBox1.SelectionLength = 0;
}


回答7:

I came across of this thread for my same issue I faced. Somehow I resolved it as below,

if (sender != null)
                {
                    e.Handled = true;
                    if((sender as TextBox).SelectionLength != 0)
                        (sender as TextBox).SelectionLength = 0;
                }

Verifying if the length changed other than 0, then only set it to 0, resolves the recursive loop.



回答8:

In WinForms, the correct method is to assign the event MouseMove and set the SelectionLength to 0.

I´ve tried here and works perfectly.



回答9:

private void textBox5_Click(object sender, EventArgs e)
{
    this.textBox5.SelectionStart = this.textBox5.Text.Length;
}