How to make a textbox non-selectable using C#

2019-04-22 00:45发布

问题:

I'm using C#/.NET for a Windows Forms application. I have a text box. How can I make the text box unselectable?

I don't want to disable the complete textbox.

回答1:

In the 'Enter' event of the textbox set the ActiveControl to something else:

    private void txtMyTextbox_Enter(object sender, EventArgs e)
    {
        ActiveControl = objMyOtherControl;
    }


回答2:

IsHitTestVisible="False" prevents the textbox from displaying the bounding box when hovering or clicking with the mouse. That was enough in my case to take benefit of the textwrapping feature of the textbox while making it insensitive to user actions



回答3:

You have a couple of options:

  1. Use a Label control instead.
  2. Set textBox.Enabled = false to prevent selection (see here).


回答4:

I had the same problem. I had a dialog up and needed multiline text to be displayed. I could not use a label as it has to be a textbox because of the multiline and text wrap.

I first mad it readonly, but if the dialog is flashed by other windows, the text becomes selected which looks horrible. So I found the problem.

In the form builder program (whatever it is called), there is a property for the TextBox called TabStop. I set that to false and the read-only textbox text never gets selected. Problem solved.



回答5:

The messages that cause text can be intercepted and blocked. I would have thought that EM_SETSEL would be all that is required. However, even when the mouse clicks and drags, there is no EM_SETEL message, but the text still selects. Possibly one of the messages has a pointer to a struct that contains the info.

Note: I'm not sure if this prevents all ways to select text.

public class TextBox2 : TextBox {

    private const int EM_SETSEL = 0x00B1;
    private const int WM_LBUTTONDBLCLK = 0x203;
    private const int WM_MOUSEMOVE = 0x200;
    private const int WM_KEYDOWN = 0x100;
    private const int VK_CONTROL = 0x11;
    private const int VK_SHIFT = 0x10;

    public TextBox2() {
        this.ShortcutsEnabled = false; // disabled right click menu
        this.Cursor = Cursors.Default;

    }

    protected override void OnGotFocus(EventArgs e) {
        base.OnGotFocus(e);
        HideCaret(this.Handle); // doesn't work from OnHandleCreated
    }

    [DllImport("user32.dll")]
    public static extern bool HideCaret(IntPtr hWnd);

    public override bool PreProcessMessage(ref Message msg) {
        // prevents the user from using the SHIFT or CTRL + arrow keys to select text
        if (msg.Msg == WM_KEYDOWN)
            return true;

        return base.PreProcessMessage(ref msg);
    }

    protected override void WndProc(ref Message m) {
        if (m.Msg == EM_SETSEL || m.Msg == WM_MOUSEMOVE || m.Msg == WM_LBUTTONDBLCLK)
            return;

        base.WndProc(ref m);
    }
}


回答6:

Probably the best way is to put a label behind it, and when you want to make the textbox disabled, hide it and show the label in its place.



回答7:

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

And don't forget that: read only=true



回答8:

Try using CanFocus property.



回答9:

@Mystere Man: You might want a text box that cannot be used all the time. For example, I allow the user to create text boxes on a canvas and drag them around. To prevent them from selecting and moving text when they are dragging I need to disallow user input, and text selection also needs to be disabled because it causes a delay which messes up my drag function. In my application the user can only edit a text box when he has double clicked on it, and must then click outside of the text box to be able to move it again.

I basically have this code (where t is a TextBox):

// Prevent text entry
t.IsReadOnly = true;

// Prevent text selection
t.Focusable = false;

This behaviour is preferable to disabling the whole control (t.Enabled = false), since that would also stop mousedown and doubleclick events, which would stop dragging and changing from edit to drag mode from working. Not to mention that the text box would go grey.



回答10:

This has worked just fine to me:

textBox.ReadOnly = true