WPF技术问题:能否在单个TextBox中为服务器地址的Http/Https前缀设不同颜色?
实现单个TextBox内区分URL前缀颜色的方案
当然可以实现!完全不需要拆分多个TextBox,不管你用的是WinForms、WPF还是其他桌面框架,都有合适的方案来让http:///https://前缀和链接其余部分显示不同颜色。下面分两种常见框架给出具体实现思路:
一、WinForms 方案:自定义绘制TextBox
普通的TextBox默认不支持多颜色文本,但我们可以通过继承TextBox并自定义绘制逻辑来实现:
自定义控件代码
using System; using System.Drawing; using System.Linq; using System.Windows.Forms; public class ColoredUrlTextBox : TextBox { public ColoredUrlTextBox() { // 开启双缓冲避免绘制闪烁 DoubleBuffered = true; // 开启用户自定义绘制模式 SetStyle(ControlStyles.UserPaint, true); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); string inputText = this.Text; if (string.IsNullOrEmpty(inputText)) return; // 定义需要高亮的前缀和对应颜色 string[] targetPrefixes = { "http://", "https://" }; Color prefixColor = Color.DodgerBlue; Color restTextColor = this.ForeColor; // 查找匹配的前缀(忽略大小写) string matchedPrefix = targetPrefixes.FirstOrDefault(p => inputText.StartsWith(p, StringComparison.OrdinalIgnoreCase)); if (matchedPrefix != null) { // 绘制前缀部分 e.Graphics.DrawString(matchedPrefix, this.Font, new SolidBrush(prefixColor), 0, 0); // 计算前缀的宽度,绘制剩余文本 SizeF prefixSize = e.Graphics.MeasureString(matchedPrefix, this.Font); string restText = inputText.Substring(matchedPrefix.Length); e.Graphics.DrawString(restText, this.Font, new SolidBrush(restTextColor), prefixSize.Width, 0); } else { // 没有匹配前缀,正常绘制全部文本 e.Graphics.DrawString(inputText, this.Font, new SolidBrush(restTextColor), 0, 0); } } protected override void OnTextChanged(EventArgs e) { base.OnTextChanged(e); // 文本变化时触发重绘 Invalidate(); } }
使用方法
编译这段代码后,你的WinForms工具箱里会出现ColoredUrlTextBox控件,直接拖到窗体上使用即可——输入包含http://或https://的地址时,前缀会自动显示为蓝色,其余部分保持默认文本颜色。
二、WPF 方案:利用RichTextBox动态设置样式
WPF的RichTextBox天然支持多格式文本,我们可以监听文本变化事件,动态给前缀和剩余部分设置不同颜色:
XAML 布局代码
<Window x:Class="UrlTextBoxDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="URL输入框" Height="100" Width="400"> <Grid> <RichTextBox x:Name="urlInputBox" BorderThickness="1" BorderBrush="#CCCCCC" Height="35" TextChanged="UrlInputBox_TextChanged"> <RichTextBox.Resources> <!-- 移除默认段落边距,让输入框更像普通TextBox --> <Style TargetType="Paragraph"> <Setter Property="Margin" Value="0"/> </Style> </RichTextBox.Resources> </RichTextBox> </Grid> </Window>
后台逻辑代码
using System; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; namespace UrlTextBoxDemo { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void UrlInputBox_TextChanged(object sender, TextChangedEventArgs e) { var rtb = sender as RichTextBox; if (rtb == null || string.IsNullOrEmpty(rtb.Text)) return; // 清空原有内容,重新构建文本块 rtb.Document.Blocks.Clear(); Paragraph para = new Paragraph(); string[] targetPrefixes = { "http://", "https://" }; string matchedPrefix = targetPrefixes.FirstOrDefault(p => rtb.Text.StartsWith(p, StringComparison.OrdinalIgnoreCase)); if (matchedPrefix != null) { // 前缀设置为蓝色 Run prefixRun = new Run(matchedPrefix) { Foreground = Brushes.DodgerBlue, FontFamily = rtb.FontFamily, FontSize = rtb.FontSize }; para.Inlines.Add(prefixRun); // 剩余文本保持默认颜色 Run restRun = new Run(rtb.Text.Substring(matchedPrefix.Length)) { Foreground = Brushes.Black, FontFamily = rtb.FontFamily, FontSize = rtb.FontSize }; para.Inlines.Add(restRun); } else { // 无前缀时正常显示 para.Inlines.Add(new Run(rtb.Text) { Foreground = Brushes.Black, FontFamily = rtb.FontFamily, FontSize = rtb.FontSize }); } rtb.Document.Blocks.Add(para); // 保持光标在文本末尾 rtb.CaretPosition = rtb.Document.ContentEnd; } } }
这个方案看起来和普通TextBox几乎一样,但能完美实现你要的多颜色显示效果。
内容的提问来源于stack exchange,提问作者Christian Lüdeking
相关产品推荐
相关产品推荐

