禁止在文本框中选择文本

11

我有一个文本框,具有以下(重要)属性:

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

它看起来像这样:

带有突出显示文本的文本框

我如何禁止用户在此文本框中突出显示文本(但我不想完全禁用文本框)?


它会有垂直滚动条吗? - Victor
3
WinForms?WPF?这是什么样的“RichTextBox”? - Mike Perrenoud
4
这段代码需要翻译成中文,且保持原意但更加易懂:@BigM写的this.license.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;是针对winforms的。 - tukaef
13个回答

12

附加到 SelectionChanged 事件,然后在事件内设置 e.Handled = true;SelectionLength = 0;,这将停止选择发生。这类似于防止按键操作发生的方法。


13
我无法找到适用于WinForms TextBox控件的该事件。 - checho
4
如果你感兴趣的话,我遇到了和你一样的问题,但是通过使用WinForms RichTextBox控件解决了它,这个控件很幸运地有“SelectionChanged”事件。 - Calcolat
2
使用TextBox做这件事会导致递归循环和StackOverflowException。在SelectionChanged回调中更改选择是一个不好的想法! - floydheld
@floydheld 在 SelectionAll 之前注销处理程序,然后在之后再次注册以防止 StackOverflowException。 - Lukáš Koten

9
如果您将文本放入标签中,然后将该标签放入已开启AutoScrollSystem.Windows.Forms.Panel控件中,则可以显示文本而无需选择。

1
一个更好的解决方案。没有任何黑科技来让文本框工作。 - tdemay
@pitersmx https://dev59.com/mHM_5IYBdhLWcg3w2W9g - JG in SD

8
为了禁用TextBox中的选择高亮,您可以重写WndProc并处理WM_SETFOCUS消息,将其替换为WM_KILLFOCUS。请注意,这不会使TextBox控件只读,如果您需要使其只读,还应将ReadOnly属性设置为true。如果您将ReadOnly设置为true,则可以设置它的BackColorWhite或任何其他适合您的颜色。
在下面的代码中,我添加了一个SelectionHighlightEnabled属性到MyTextBox,使启用或禁用选择高亮变得容易:
  • SelectionHighlightEnabled:获取或设置一个值,指示是否启用选择高亮。默认情况下,该值为true,就像普通的TextBox一样。如果将其设置为false,则不会呈现选择高亮。
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);
    }
}

运行良好。您可能还想将“光标”更改为默认值(而不是文本选择 IBeam 指针)。 - intrepidis
@intrepidis 谢谢,很有道理。此外,由于它并不使控件只读,如果您需要将其设置为只读,还应将ReadOnly属性设置为true,并且在启用只读时可能还要将BackColor设置为白色。 - Reza Aghaei
我的输入光标消失了。 - Thomas Weller

2

我遇到了与这个线程相同的问题。我按照以下步骤解决了它:

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

验证长度是否改变,如果不为0,则将其设置为0,解决递归循环。


在哪个事件中?mousedown事件没有e.handled属性... - Roberto D V Leonardo

1

非常简单的解决方案

找到一个标签并进入文本框的mousedown事件,将焦点设置为该标签

这是使用VB编写的,可以很容易地转换为C#

Private Sub RichTextBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles RichTextBox1.MouseDown
        Label1.Focus()
    End Sub

1

由于标准TextBox没有SelectionChanged事件,因此我想出了以下解决方案。

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

另外,为了更好的解决方案,您可以向 clamchoda answer 添加事件,例如:MouseLeaveKeyPressMouseLeave 用于在鼠标不再位于文本框区域时取消选择,而 KeyPress 用于在用户按下 Shift + Key Up/Down 进行选择时取消选择。 - Death GOD 7

0

如果您正在使用XAML / WPF,则应使用而不是。

仅当您将TextBox用作显示而非输入时 - 因为TextBlock使文本似乎“刻在”表单本身上,而不是在文本框内。如果您希望在TextBlock周围获得边框,则可以执行以下操作:

XAML中,例如:

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

或者在 C# 代码 中动态地:

//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;

0
对于多行文本,标签无法胜任。我的解决方案是在文本框上设置Enter事件并将焦点重定向到其他地方。例如:
    private void textBox1_Enter(object sender, EventArgs e)
    {
        this.anotherControl.Focus(); // Preferably a readonly control in case the user starts typing
    }

0

您可以使用禁用的 RichTextBox,然后将颜色重置为黑色。

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接