使用方法:
和Label组件一样用,自动解析Text中指数部分,并以上标显示出来。例如:3.2x^5+2x^3-1.2x^2+5.4x……
效果图:
下面的显示部分的3个文本框……
代码:
本来为了提高速度,用了个Bitmap _bmp;字段,文本更改的时候重新绘制到_bmp里,这样OnPaint()的时候就绘制这个图片就行了,后来发现绘制_bmp的时候里面的文字就变的十分丑陋了,TextRenderingHint改成ClearTypeGridFit没有效果,AntiAlias会好点,不过就模糊了,,不如直接在OnPaint方法里DrawString时的ClearType效果…………谁有好办法告诉我声~~~
/**//*
* Copyright (c) 2008 黑色珊瑚::DS.Controls, Reserved.
*
* Filename: @(#)TsMathLabel.cs
* Create by: TsOrgY
* Email: tsorgy@gmail.com
* Date: 2008/12/4 20:05:36
*
* Classname: TsMathLabel
* Description: 多项式标签,可以按照数学模式来显示多项式(显示上标)
* 格式:3x^2+2.3x^1-1.2x^4+
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
namespace DS.Controls
{
/**//// <summary>
/// 多项式标签
/// </summary>
public class TsMathLabel : Label
{
* StringPie *#region * StringPie *
/**//// <summary>
/// 字符串片段类
/// </summary>
private class StringPie
{
/**//// <summary>
/// 文本
/// </summary>
public string Text { get; set; }
/**//// <summary>
/// 坐标
/// </summary>
public PointF Location { get; set; }
/**//// <summary>
/// 左边距
/// </summary>
public float Left { get { return Location.X; } }
/**//// <summary>
/// 右边距
/// </summary>
public float Top { get { return Location.Y; } }
/**//// <summary>
/// 是否上标
/// </summary>
public bool IsIndex { get; set; }
public StringPie(string txt, float x, float y, bool isIndex)
{
this.Text = txt;
this.Location = new PointF(x, y);
this.IsIndex = isIndex;
}
}
#endregion
-私有字段-#region -私有字段-
/**//// <summary>
/// 字符串片段
/// </summary>
private StringPie[] _strs;
/**//// <summary>
/// 小字体
/// </summary>
private Font _fontSmall;
#endregion
-构造-#region -构造-
public TsMathLabel()
: base()
{
this._fontSmall = new Font(this.Font.FontFamily, this.Font.Size * 3.0f / 4.0f, this.Font.Style);
RefreshBitmap();
}
#endregion
-私有方法-#region -私有方法-
/**//// <summary>
/// 刷新呈现图像
/// </summary>
private void RefreshBitmap()
{
Graphics g = this.CreateGraphics();
List<StringPie> lst = new List<StringPie>();
// 当前坐标
float xoffset = 0.0f;
float yoffset = 0.0f;
// 小字体计算宽度出现偏差
float xoffset1 = g.MeasureString("0", this._fontSmall).Width / 3;
// 开始循环
string[] txts = this.Text.Split('\n');
for (int n = 0; n < txts.Length; n++)
{
List<StringPie> strs = new List<StringPie>();
// 取得一行文本,eg: 3x^6+4.3x^12
string txt = txts[n];
bool flag = true; // 标志最后还有没有文字
for (int i; (i = txt.IndexOf('^')) >= 0; )
{
// 系数+x
string s1 = txt.Substring(0, i);
strs.Add(new StringPie(s1, xoffset, yoffset, false));
xoffset += g.MeasureString(s1, this.Font).Width;
if (++i >= txt.Length)
{
flag = false;
break;
}
txt = txt.Substring(i); // txt 现在是 "6+4.3x^12"
// 指数
int j = 0;
for (; j < txt.Length; j++)
if (j > 0 && (txt[j] == '+' || txt[j] == '-'))
break;
string s2 = txt.Substring(0, j);
strs.Add(new StringPie(s2, xoffset - xoffset1, yoffset, true));
xoffset += g.MeasureString(s2, this._fontSmall).Width - xoffset1 * 2;
if (j >= txt.Length)
{
flag = false;
break;
}
txt = txt.Substring(j); // txt 现在是 "6+4.3x^12"
}
// 加上剩余的字串
if (flag)
{
strs.Add(new StringPie(txt, xoffset, yoffset, false));
xoffset += g.MeasureString(txt, this.Font).Width;
}
/**//*
* 如果文本右对齐,就平移横坐标
* 不考虑垂直和居中了,如果要那些效果可以在这加
* 另外这是简单的左对齐右对齐,不考虑文字超出部分的情况
*/
if (this.TextAlign == ContentAlignment.MiddleRight ||
this.TextAlign == ContentAlignment.BottomRight ||
this.TextAlign == ContentAlignment.TopRight)
{
foreach (StringPie sp in strs)
sp.Location = new PointF(sp.Left + this.Width - xoffset - xoffset1, sp.Top);
}
lst.AddRange(strs);
xoffset = 0.0f;
yoffset += this.FontHeight;
}
this._strs = lst.ToArray();
g.Dispose();
}
#endregion
-重写-#region -重写-
/**//// <summary>
/// 绘制
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
//base.OnPaint(e);
Graphics g = e.Graphics;
Brush brush = new SolidBrush(this.ForeColor);
g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; // ClearType 文字渲染
foreach (StringPie sp in this._strs)
g.DrawString(sp.Text, (sp.IsIndex ? this._fontSmall : this.Font), brush, sp.Location);
}
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
this._fontSmall = new Font(this.Font.FontFamily, this.Font.Size * 3.0f / 4.0f, this.Font.Style);
RefreshBitmap();
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
RefreshBitmap();
}
protected override void OnTextAlignChanged(EventArgs e)
{
base.OnTextAlignChanged(e);
RefreshBitmap();
}
#endregion
}
}