110,534
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsFormsApplication1
{
class SuperLinkLabel : LinkLabel
{
public bool IgnoreCase { get; set; }
private string keyWord = "";
public string Keyword
{
get { return keyWord; }
set { keyWord = value; this.Invalidate(); }
}
public Color KeywordColor { get; set; }
public SuperLinkLabel()
{
Keyword = "";
KeywordColor = Color.Red;
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Control), e.ClipRectangle);
StringFormat stringFormat = new StringFormat();
stringFormat.SetMeasurableCharacterRanges(GetRanges());
stringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
Region[] regions = e.Graphics.MeasureCharacterRanges(Text, Font, new RectangleF(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width + 200, e.ClipRectangle.Height), stringFormat);
int i = 0;
foreach (var item in GetStringRgn().ToList())
{
bool isKeyword = GetStringRgn().Single(x => x.Item1 == item.Item1).Item3;
e.Graphics.DrawString(Text.Substring(item.Item1, item.Item2 - item.Item1 + 1), Font, isKeyword ? new SolidBrush(KeywordColor) : new SolidBrush(LinkColor), new PointF(regions[i].GetBounds(e.Graphics).X, regions[i].GetBounds(e.Graphics).Y), stringFormat);
i++;
}
}
private CharacterRange[] GetRanges()
{
return GetStringRgn().ToArray().Select(x => new CharacterRange(x.Item1, x.Item2 - x.Item1 + 1)).ToArray();
}
private IEnumerable<Tuple<int, int, bool>> GetStringRgn()
{
if (Keyword == "" || Text == "")
{
if (Text == "") yield break;
yield return new Tuple<int, int, bool>(0, Text.Length - 1, false);
yield break;
}
int pre = 0;
int i = 0;
while (i <= Text.Length - Keyword.Length)
{
if (Text.Substring(i, Keyword.Length).ToUpper() == Keyword.ToUpper())
{
if (IgnoreCase || Text.Substring(i, Keyword.Length) == Keyword)
{
if (pre != i) yield return new Tuple<int, int, bool>(pre, i - 1, false);
yield return new Tuple<int, int, bool>(i, i + Keyword.Length - 1, true);
i += Keyword.Length;
pre = i;
}
else
{
i++;
}
}
else
{
i++;
}
}
if (pre <= Text.Length - 1) yield return new Tuple<int, int, bool>(pre, Text.Length - 1, false);
}
}
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Control), e.ClipRectangle);
var pattern = string.Format("({0}|\n)", Keyword);
string[] strings = Regex.Split(Text, pattern, IgnoreCase ? RegexOptions.IgnoreCase : RegexOptions.None);
int lineHeight = TextRenderer.MeasureText(e.Graphics, "A", Font).Height * 3 / 2;
var pt = new Point();
Size proposedSize = new Size(int.MaxValue, int.MaxValue);
var flags = TextFormatFlags.NoPadding;
foreach (var str in strings)
{
if (str != "\n")
{
var sz = TextRenderer.MeasureText(e.Graphics, str, Font, proposedSize, flags);
var color = str.Equals(keyWord, IgnoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture) ?
KeywordColor : LinkColor;
TextRenderer.DrawText(e.Graphics, str, Font, pt, color, flags);
pt.X += sz.Width;
}
else
{
pt = new Point(0, pt.Y + lineHeight);
}
}
}
//Region[] regions =
//e.Graphics.MeasureCharacterRanges(Text, Font,
//new RectangleF(
// e.ClipRectangle.X,
// e.ClipRectangle.Y,
// e.ClipRectangle.Width + 200,
// e.ClipRectangle.Height),
// stringFormat);
Region[] regions =
e.Graphics.MeasureCharacterRanges(Text, Font,
new RectangleF(
this.ClientRectangle.X,
this.ClientRectangle.Y,
this.ClientRectangle.Width + 200,
this.ClientRectangle.Height),
stringFormat);
PointF ptf = new PointF(regions[i].GetBounds(e.Graphics).X,
regions[i].GetBounds(e.Graphics).Y);
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Control), e.ClipRectangle);
StringFormat stringFormat = new StringFormat();
stringFormat.SetMeasurableCharacterRanges(GetRanges());
stringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
Region[] regions = e.Graphics.MeasureCharacterRanges(Text,
Font,
new RectangleF(this.ClientRectangle.X,
this.ClientRectangle.Y,
4000,
4000),
stringFormat);
e.Graphics.DrawString(Text,
Font,
new SolidBrush(LinkColor),
new Point(this.ClientRectangle.X, this.ClientRectangle.Y),
stringFormat);
int i = 0;
foreach (var item in GetStringRgn().ToList())
{
bool isKeyword = GetStringRgn().Single(x => x.Item1 == item.Item1).Item3;
if (isKeyword)
{
PointF ptf = new PointF(regions[i].GetBounds(e.Graphics).X-3,
regions[i].GetBounds(e.Graphics).Y);
e.Graphics.FillRegion(new SolidBrush(BackColor), regions[i]);
e.Graphics.DrawString(Text.Substring(item.Item1, item.Item2 - item.Item1 + 1),
Font,
new SolidBrush(KeywordColor),
ptf,
stringFormat);
}
i++;
}
}
private IEnumerable<Tuple<int, int, bool>> GetStringRgn()
{
if (Keyword == "" || Text == "")
{
if (Text == "") yield break;
yield return new Tuple<int, int, bool>(0, Text.Length - 1, false);
yield break;
}
int i = 0;
while (i <= Text.Length - Keyword.Length)
{
if (Text.Substring(i, Keyword.Length).ToUpper() == Keyword.ToUpper())
{
if (IgnoreCase || Text.Substring(i, Keyword.Length) == Keyword)
{
yield return new Tuple<int, int, bool>(i, i + Keyword.Length - 1, true);
i += Keyword.Length;
continue;
}
}
i++;
}
}
//Region[] regions =
//e.Graphics.MeasureCharacterRanges(Text, Font,
//new RectangleF(
// e.ClipRectangle.X,
// e.ClipRectangle.Y,
// e.ClipRectangle.Width + 200,
// e.ClipRectangle.Height),
// stringFormat);
Region[] regions =
e.Graphics.MeasureCharacterRanges(Text, Font,
new RectangleF(
this.ClientRectangle.X,
this.ClientRectangle.Y,
this.ClientRectangle.Width + 200,
this.ClientRectangle.Height),
stringFormat);
[/quote]
谢谢你的修改。果然是这样。
不过还有一个多行的bug,你有兴趣试试么?我搞不定了。
这是我的提问帖。
http://social.msdn.microsoft.com/Forums/vstudio/en-US/0c4cda67-8832-450a-9242-7621a10d7b60/a-problem-about-create-a-keyword-highlighted-linkedlabel#0c4cda67-8832-450a-9242-7621a10d7b60