如何扩展 RichTextbox 着色函数来为字符串的部分着色?
How to extend a RichTextbox coloring function to color parts of strings?
private void ColorRichTextbox(RichTextBox box, string text, Color color)
{
int length = MyRichTextBox.TextLength;
if (!string.IsNullOrWhiteSpace(MyRichTextBox.Text))
{
MyRichTextBox.AppendText("\r\n" + text);
}
else
{
MyRichTextBox.AppendText(text);
}
MyRichTextBox.SelectionStart = length;
MyRichTextBox.SelectionLength = text.Length;
MyRichTextBox.SelectionColor = color;
}
用法:
ColorRichTextbox(MyRichTextBox,
"This is example : " + DateTime.Now, Color.Red);
结果是红色一行,由“This is example :”和 DateTime.Now
部分组成。有没有办法让“This is example :”部分变成白色,DateTime.Now
变成红色?
如果您修改您的方法以不总是将文本强制排在自己的行上,您可以调用它两次 - 首先是白色文本,然后是红色文本:
private void ColorRichTextbox(RichTextBox box, string text, Color color, bool appendNewLine = true)
{
int length = box.TextLength;
if (!string.IsNullOrWhiteSpace(box.Text) && appendNewLine)
{
box.AppendText("\r\n" + text);
}
else
{
box.AppendText(text);
}
box.SelectionStart = length;
box.SelectionLength = text.Length;
box.SelectionColor = color;
}
通过将 appendNewLine
设置为 false
,输入的文本将不会放在单独的行中,因此从上一个调用停止的地方继续:
ColorRichTextbox(MyRichTextBox, "This is example : ", Color.White);
ColorRichTextbox(MyRichTextBox, DateTime.Now.ToString(), Color.Red, false); // false = Don't write this text on a separate line
旁注:您似乎没有使用方法的 box
参数。如果你想将它用于多个 RichTextBox,你应该在你的方法中将 MyRichTextBox
替换为 box
(这已在我上面的代码中完成)。
结果:
您也可以使用自定义内插字符串处理程序来执行此操作。
richTextBox1.AppendColoredLine($"This is an example : {DateTime.Now:red}");
richTextBox1.AppendColoredLine($"This is an example : {DateTime.Now:green}");
richTextBox1.AppendColoredLine($"This is an example : {DateTime.Now:blue}");
richTextBox1.AppendColoredLine($"This is an example : {DateTime.Now:yellow}");
richTextBox1.AppendColoredLine($"Some other colored things: {"hi":orange}, {10:purple}, {this.Name:gray}");
这是使其工作的代码(需要 .Net 6):
using System;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace YourNamespace;
public static class RichTextBoxExtensions
{
[InterpolatedStringHandler]
[StructLayout(LayoutKind.Auto)]
public ref struct ColoredStringHandler
{
private readonly RichTextBox textBox;
private readonly IFormatProvider? formatProvider;
public ColoredStringHandler(int literalLength, int formattedCount, RichTextBox textBox, IFormatProvider? formatProvider = null)
{
this.textBox = textBox;
this.formatProvider = formatProvider;
textBox.DeselectAll();
}
public void AppendLiteral(string s) => textBox.AppendText(s);
public void AppendFormatted<T>(T item) where T : notnull => AppendLiteral(item.ToString() ?? "");
public void AppendFormatted<T>(T item, string format) where T : notnull
{
var color = Color.FromName(format);
string? s =
item is IFormattable
? ((IFormattable)(object)item).ToString(null, formatProvider)
: item.ToString();
s ??= "";
Color previousColor = textBox.SelectionColor;
try
{
textBox.SelectionColor = color;
textBox.AppendText(s);
}
finally
{
textBox.SelectionColor = previousColor;
}
}
}
public static void AppendColored(this RichTextBox textBox, IFormatProvider? formatProvider,
[InterpolatedStringHandlerArgument("textBox", "formatProvider")] ref ColoredStringHandler handler)
{
}
public static void AppendColored(this RichTextBox textBox,
[InterpolatedStringHandlerArgument("textBox")] ref ColoredStringHandler handler)
{
}
public static void AppendColoredLine(this RichTextBox textBox, IFormatProvider? formatProvider,
[InterpolatedStringHandlerArgument("textBox", "formatProvider")] ref ColoredStringHandler handler)
{
textBox.AppendText(Environment.NewLine);
}
public static void AppendColoredLine(this RichTextBox textBox,
[InterpolatedStringHandlerArgument("textBox")] ref ColoredStringHandler handler)
{
textBox.AppendText(Environment.NewLine);
}
}
private void ColorRichTextbox(RichTextBox box, string text, Color color)
{
int length = MyRichTextBox.TextLength;
if (!string.IsNullOrWhiteSpace(MyRichTextBox.Text))
{
MyRichTextBox.AppendText("\r\n" + text);
}
else
{
MyRichTextBox.AppendText(text);
}
MyRichTextBox.SelectionStart = length;
MyRichTextBox.SelectionLength = text.Length;
MyRichTextBox.SelectionColor = color;
}
用法:
ColorRichTextbox(MyRichTextBox,
"This is example : " + DateTime.Now, Color.Red);
结果是红色一行,由“This is example :”和 DateTime.Now
部分组成。有没有办法让“This is example :”部分变成白色,DateTime.Now
变成红色?
如果您修改您的方法以不总是将文本强制排在自己的行上,您可以调用它两次 - 首先是白色文本,然后是红色文本:
private void ColorRichTextbox(RichTextBox box, string text, Color color, bool appendNewLine = true)
{
int length = box.TextLength;
if (!string.IsNullOrWhiteSpace(box.Text) && appendNewLine)
{
box.AppendText("\r\n" + text);
}
else
{
box.AppendText(text);
}
box.SelectionStart = length;
box.SelectionLength = text.Length;
box.SelectionColor = color;
}
通过将 appendNewLine
设置为 false
,输入的文本将不会放在单独的行中,因此从上一个调用停止的地方继续:
ColorRichTextbox(MyRichTextBox, "This is example : ", Color.White);
ColorRichTextbox(MyRichTextBox, DateTime.Now.ToString(), Color.Red, false); // false = Don't write this text on a separate line
旁注:您似乎没有使用方法的 box
参数。如果你想将它用于多个 RichTextBox,你应该在你的方法中将 MyRichTextBox
替换为 box
(这已在我上面的代码中完成)。
结果:
您也可以使用自定义内插字符串处理程序来执行此操作。
richTextBox1.AppendColoredLine($"This is an example : {DateTime.Now:red}");
richTextBox1.AppendColoredLine($"This is an example : {DateTime.Now:green}");
richTextBox1.AppendColoredLine($"This is an example : {DateTime.Now:blue}");
richTextBox1.AppendColoredLine($"This is an example : {DateTime.Now:yellow}");
richTextBox1.AppendColoredLine($"Some other colored things: {"hi":orange}, {10:purple}, {this.Name:gray}");
这是使其工作的代码(需要 .Net 6):
using System;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace YourNamespace;
public static class RichTextBoxExtensions
{
[InterpolatedStringHandler]
[StructLayout(LayoutKind.Auto)]
public ref struct ColoredStringHandler
{
private readonly RichTextBox textBox;
private readonly IFormatProvider? formatProvider;
public ColoredStringHandler(int literalLength, int formattedCount, RichTextBox textBox, IFormatProvider? formatProvider = null)
{
this.textBox = textBox;
this.formatProvider = formatProvider;
textBox.DeselectAll();
}
public void AppendLiteral(string s) => textBox.AppendText(s);
public void AppendFormatted<T>(T item) where T : notnull => AppendLiteral(item.ToString() ?? "");
public void AppendFormatted<T>(T item, string format) where T : notnull
{
var color = Color.FromName(format);
string? s =
item is IFormattable
? ((IFormattable)(object)item).ToString(null, formatProvider)
: item.ToString();
s ??= "";
Color previousColor = textBox.SelectionColor;
try
{
textBox.SelectionColor = color;
textBox.AppendText(s);
}
finally
{
textBox.SelectionColor = previousColor;
}
}
}
public static void AppendColored(this RichTextBox textBox, IFormatProvider? formatProvider,
[InterpolatedStringHandlerArgument("textBox", "formatProvider")] ref ColoredStringHandler handler)
{
}
public static void AppendColored(this RichTextBox textBox,
[InterpolatedStringHandlerArgument("textBox")] ref ColoredStringHandler handler)
{
}
public static void AppendColoredLine(this RichTextBox textBox, IFormatProvider? formatProvider,
[InterpolatedStringHandlerArgument("textBox", "formatProvider")] ref ColoredStringHandler handler)
{
textBox.AppendText(Environment.NewLine);
}
public static void AppendColoredLine(this RichTextBox textBox,
[InterpolatedStringHandlerArgument("textBox")] ref ColoredStringHandler handler)
{
textBox.AppendText(Environment.NewLine);
}
}