我正在寻找一种在单个 C#/.NET 标签中显示多种颜色的方法。例如,标签显示了一系列 csv 分隔值,每个值根据它们落入的桶而呈现颜色。我不想使用多个标签,因为这些值是可变长度的,我不想玩动态布局。有对此的本机支持吗?
11 回答
.NET 中没有执行此操作的本机控件。您最好的选择是编写您自己的 UserControl(称之为 RainbowLabel 或其他名称)。通常你会有一个直接从Label继承的自定义标签控件,但是由于你不能在一个标签中获得多色文本,你只能从UserControl继承。
为了呈现文本,您的 UserControl 可以用逗号分割文本,然后为每个块动态加载不同颜色的标签。然而,更好的方法是使用 Graphics 命名空间中的 DrawString 和 MeasureString 方法将文本直接呈现到您的 UserControl 上。
在 .NET 中编写 UserControls 确实不难,而这种不寻常的问题正是自定义 UserControls 的用途。
更新:这是一个简单的方法,可用于在 PictureBox 上呈现多色文本:
public void RenderRainbowText(string Text, PictureBox pb)
{
// PictureBox needs an image to draw on
pb.Image = new Bitmap(pb.Width, pb.Height);
using (Graphics g = Graphics.FromImage(pb.Image))
{
// create all-white background for drawing
SolidBrush brush = new SolidBrush(Color.White);
g.FillRectangle(brush, 0, 0,
pb.Image.Width, pb.Image.Height);
// draw comma-delimited elements in multiple colors
string[] chunks = Text.Split(',');
brush = new SolidBrush(Color.Black);
SolidBrush[] brushes = new SolidBrush[] {
new SolidBrush(Color.Red),
new SolidBrush(Color.Green),
new SolidBrush(Color.Blue),
new SolidBrush(Color.Purple) };
float x = 0;
for (int i = 0; i < chunks.Length; i++)
{
// draw text in whatever color
g.DrawString(chunks[i], pb.Font, brushes[i], x, 0);
// measure text and advance x
x += (g.MeasureString(chunks[i], pb.Font)).Width;
// draw the comma back in, in black
if (i < (chunks.Length - 1))
{
g.DrawString(",", pb.Font, brush, x, 0);
x += (g.MeasureString(",", pb.Font)).Width;
}
}
}
}
显然,如果您的文本中有超过 4 个以逗号分隔的元素,这将中断,但您明白了。此外,MeasureString 中似乎存在一个小故障,使其返回的宽度比必要的宽几个像素,因此多色字符串似乎被拉长 - 您可能需要调整该部分。
为 UserControl 修改此代码应该很简单。
注意:TextRenderer 是一个更好的用于绘制和测量字符串的类,因为它使用整数。Graphics.DrawString 和 .MeasureString 使用浮点数,所以你会在这里和那里得到逐个像素的错误。
更新: 忘记使用 TextRenderer。这是狗慢。
您可以尝试使用 RichTextBox 以便您可以获得字符串的多种颜色,然后将其设为只读并删除边框。将背景颜色更改为与它所在的表单相同,您可能会侥幸成功。
作为替代方案,您可以在合适的控件(例如 WebBrowser)中以 rtf 或 html 的形式执行此操作。理想情况下,它可能需要更多的资源,但它会很快工作。
如果您正在为 XP 及更高版本的用户构建 Windows 应用程序,则可以使用 WPF。即使它是 Windows 窗体应用程序,您也可以添加 WPF 用户控件。
然后我会使用标签,并将“前景”属性设置为颜色渐变。
或者,在 Windows 窗体(无 WPF)中,您可以只使用“流程面板”,然后在 for 循环中添加多个标签作为句子的片段......它们将全部“流动”在一起,就好像它是一个标签一样.
我经常使用彩色标签将关键字标记为红色等。就像在 Phil Wright 的回答中一样,我使用 RichTextBox 控件,删除边框并将背景颜色设置为 SystemColors.Control。
要编写彩色文本,首先清除控件,然后我使用此函数附加彩色文本:
private void rtb_AppendText(Font selfont, Color color, Color bcolor,
string text, RichTextBox box)
{
// append the text to the RichTextBox control
int start = box.TextLength;
box.AppendText(text);
int end = box.TextLength;
// select the new text
box.Select(start, end - start);
// set the attributes of the new text
box.SelectionColor = color;
box.SelectionFont = selfont;
box.SelectionBackColor = bcolor;
// unselect
box.Select(end, 0);
// only required for multi line text to scroll to the end
box.ScrollToCaret();
}
如果您想使用“mono”运行此功能,则在每个新的彩色文本之前添加一个空格,否则 mono 将无法正确设置新颜色。这不是 .NET 所必需的
用法:
myRtb.Text = "";
rtb_AppendText(new Font("Courier New", (float)10),
Color.Red, SystemColors.Control, " my red text", myRtb);
rtb_AppendText(new Font("Courier New", (float)10),
Color.Blue, SystemColors.Control, " followed by blue", myRtb);
您可以简单地使用多个标签。设置你想要的字体属性,然后使用左边。top 和 width 属性来显示您想要以不同方式显示的单词。这是假设您使用的是 Windows 窗体。
试试这个,
labelId.Text = "Successfully sent to" + "<a style='color:Blue'> " + name + "</a>";
对此没有本机支持;您将不得不使用多个标签或找到将提供此功能的第 3 方控件。
我不这么认为。您应该自己创建一个。
根据您的问题,您的要求很简单
lable.Text = "This color is Red"
,所以它必须显示这样的文本“颜色是”将是蓝色,“红色”将是红色......这可以这样完成
lable.Text = "<span style='Color:Blue'>" + " The color is " +"</span>" + "<span style='Color:Red'>"Red"</span>"