如何在 C# Winforms 程序的文本框中突出显示文本?

Posted

技术标签:

【中文标题】如何在 C# Winforms 程序的文本框中突出显示文本?【英文标题】:How do I highlight Text in a Textbox in a C# Winforms program? 【发布时间】:2011-01-25 15:24:26 【问题描述】:

我有一个带有多个文本框的 C# Winforms 程序。我使用每个框的属性在其中放置文本,向用户解释其中的值。每当用户选择该框时,我希望文本突出显示。通过 Tab 键或鼠标单击。如果有办法在文本框之外的某个地方显示什么值,我就不必这样做了。

我尝试了 Textbox.select 方法,但没有效果。与this 相同。

这是我的程序的Screenshot。

我的代码:

    private void grapplingText1_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
    
        grapplingText1.SelectionStart = 0;
        grapplingText1.SelectionLength = grapplingText1.Text.Length;

会这样做,还是需要更多?

【问题讨论】:

如果您尝试了两种解决方案...第二个应该有效...这可能是代码中的错误。能否提供您实际使用的代码? 我发布了代码。让我知道这是否足够继续。 那么有什么解决方案可以帮助您实现您想要实现的目标吗? 我能够完成使用标签,但我已经添加了水印。 截图链接失效。 【参考方案1】:

您如何将ToolTip 分配给TextBox 并将所有“谈论文本框的用途”放在其中?

只需将ToolTip 拖放到表单中即可。然后在每个TextBox 属性中,您应该在toolTip1 上的Misc 部分ToolTip 中有额外的条目(或者如果您重命名它,它的名称将是任何名称)。

然后,当用户将鼠标悬停在 TextBox(只读/禁用 TextBox 似乎不显示工具提示)并停在那里 1 秒钟时,工具提示应该显示正确的信息。

您最终甚至可以在 TextBox 旁边添加一个 Label 来说明是什么,但拥有一个 ToolTip 也是一个向用户解释更多信息的好主意。

为了使用 WaterMark 做一些事情,这样您就不必通过设置事件、照顾 SelectAll 等来做很长的路要走,您可以这样做。创建新的 watermark.cs 文件并用此代码替换它。确保您已更改命名空间以匹配您的程序命名空间。

#region
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

#endregion

namespace Watermark 
    public static class TextBoxWatermarkExtensionMethod 
        private const uint ECM_FIRST = 0x1500;
        private const uint EM_SETCUEBANNER = ECM_FIRST + 1;
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
        public static void SetWatermark(this TextBox textBox, string watermarkText) 
            SendMessage(textBox.Handle, EM_SETCUEBANNER, 0, watermarkText);
        
    

   internal class WatermarkTextBox : TextBox 
    private const uint ECM_FIRST = 0x1500;
    private const uint EM_SETCUEBANNER = ECM_FIRST + 1;
    private string watermarkText;
    public string WatermarkText 
        get  return watermarkText; 
        set 
            watermarkText = value;
            SetWatermark(watermarkText);
        
    
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
    private void SetWatermark(string watermarkText) 
        SendMessage(Handle, EM_SETCUEBANNER, 0, watermarkText);
    

在您的表单中,您可以这样激活它:

textBoxYourWhatever.SetWatermark("Text that should display");

只要TextBox 为空,它就会一直存在。当用户进入TextBox 时,文本消失。当TextBox 被清理(由用户或自动)时,它会再次出现。不需要任何特殊活动等。

编辑:

我还添加了内部类 WaterMarkTextBox,它使您可以选择简单地使用在 Designer 中可用的新 WaterMarkTexBox。然后将其拖放到您的设计师并使用它。它的行为与普通文本框一样,只是为您提供了额外的 WaterMarkText 字段。

我还是更喜欢你的第一种方法。不会让你再次重建你的 gui。

【讨论】:

我试过了,我得到的错误是:扩展方法必须在***静态类中定义; TextBoxWatermarkExtensionMethod 是一个嵌套类我做错了什么?此外,.SetWatermark 未在自动完成中列出。 我猜测,从那个错误中,你已经把 Extensions 类放在另一个类中。你不能这样做。它必须是***课程。完成此操作并编译后,SetWatermark 将显示在 IntelliSense 中。 我已经编辑了代码,以便您可以创建新类(单击解决方案资源管理器,然后右键单击您的程序,然后添加 -> 类。用代码替换其中的所有内容。更改水印命名空间以匹配您的程序命名空间。【参考方案2】:

如果您知道要选择的文本数量,我认为 .select 会起作用。

试试 .SelectAll();它应该适合你

【讨论】:

【参考方案3】:

您需要使用 TextBox.Focus() 将焦点放在您的控件上,如果不能自动工作,则只需在 Enter() 事件上调用 SelectAll() 方法。

private TextBox1_Enter(object sender, EventArgs e)     
    TextBoxTextHighlight(sender, null);


private TextBox2_Enter(object sender, EventArgs e) 
    TextBoxTextHighlight(sender, null);


private TextBox3_Enter(object sender, EventArgs e) 
    TextBoxTextHighlight(sender, null);


// And so forth...

private void TextBoxTextHighlight(object sender, EventArgs e) 
    (sender as TextBox).SelectAll();

此方法将允许您从任何 TextBoxX_Enter() 事件处理程序中调用它。

否则,您甚至可以创建一个新的 UserControl,在创建时随意调用它,然后在创建到您的项目时,编辑代码并将 UserControl 类的继承替换为 TextBox 类,然后在其中定义默认值您希望在 Enter() 事件上具有的行为,例如对 SelectAll() 方法的调用,并使其成为受保护的虚拟,并且在构造函数中,您可以像这样订阅事件处理程序:

public partial class CustomTextBox : TextBox 
    public CustomTextBox() 
        : base() 
        this.Enter += new EventHandler(Enter);
    

    protected virtual Enter(object sender, EventArgs e) 
        this.SelectAll();
    

我是即时编写的,因此可能需要进行一些修改,但您可能会明白。但我不建议你这样做,除非它真的适合你的适当情况。越简单越好,最简单的方法是为表单的每个 TextBoxes 创建一个事件处理程序,然后调用 TextBoxTextHighlight() 方法。

【讨论】:

在每个 TextBox 的属性窗口事件列表中双击事件 Enter() 将允许您在 TextBox1_Enter() 事件处理程序中编写代码行并传播 SelectAll() 的功能,而无需太多的努力。所以是的,对于每个 TextBox。【参考方案4】:

假设您的文本框的名称是 'MyTextBox'

您可以编写处理焦点事件的方法:

private void MyTextBox_GotFocus(object sender, EventArgs e)

    MyTextBox.SelectionStart = 0;
    MyTextBox.SelectionLength = MyTextBox.Text.Length;
    MyTextBox.Select();

您还需要添加事件处理程序:

this.MyTextBox.GotFocus += new System.EventHandler(this.MyTextBox_GotFocus);

这应该可以...

编辑

您可以对其他文本框使用相同的方法,只需添加事件处理程序:

this.MyTextBox2.GotFocus += new System.EventHandler(this.MyTextBox_GotFocus);
this.MyTextBox3.GotFocus += new System.EventHandler(this.MyTextBox_GotFocus);
this.MyTextBox4.GotFocus += new System.EventHandler(this.MyTextBox_GotFocus);
//...

【讨论】:

是的,至少,我用这段代码做了一个测试,它工作正常=) 我将 mytextbox 的所有实例替换为我的实际文本框的名称,对吧? 对,MyTextBox 只是我选择的名称,仅作为示例。但是您不需要更改 MyTextBox_GotFocus 方法的名称。 我真的会像马特建议的那样使用水印,然后对事件进行艰难的处理。我已经更新了我的帖子你应该怎么做,这似乎是最好的方法(除了使用Label/ToolTip【参考方案5】:

通常,如果您想向用户解释 文本框的内容,您可以在其正上方(或侧面)放置一个 Label 控件.

但有时,为了节省屏幕空间,您可以在文本框本身的 inside 中放置文本描述。这称为watermark。

【讨论】:

那么文本框目前在其中显示文本描述,那么您所说的水印就是这个意思吗? Watermark 就像一个内置文本,当用户尝试在该 TextBox 中输入内容时,您无需处理它。 TextBox 为空时它总是显示,当有 Text Inside 时它就消失了。 对。水印的一个很好的例子是 *** 右上角的搜索文本框。水印的缺点是当它被填写时你无法分辨出该值的含义。看看你的截图,我不得不建议你使用标签控件,直接放在文本框的上方。【参考方案6】:

将鼠标悬停在项目上时显示一些附加信息的最简单方法是使用工具提示。我尝试了类似的水印方法,但发现没有直接的方法来实现它,工具提示似乎是一个合适的替代方案。

您可以在以下链接中查看如何实现它: Implementing a tooltip

【讨论】:

检查我的答案以立即实现水印。易于实施和使用。【参考方案7】:

我发现在我的应用程序中,将 highlight 方法附​​加到 Focus -> Enter 事件并不能很好地与 SelectAll() 方法一起使用。我改为使用 Action -> Click (我相信它只适用于鼠标)并在那里附加我的突出显示方法。现在它就像一个魅力。

【讨论】:

以上是关于如何在 C# Winforms 程序的文本框中突出显示文本?的主要内容,如果未能解决你的问题,请参考以下文章

c# winforms如何保存用户输入的数据

RichTextBox C# 设置插入符号位置 winforms

如何将文本框文本拆分为列表框 C#

C#如何从表单中的文本框中获取文本,从不同的类调用

SQL注入在winforms中有效吗?

具有语法突出显示的文本框/富文本框? [C#] [关闭]