之前開發(fā)一個(gè)小工具,內(nèi)部實(shí)現(xiàn)一個(gè)狀態(tài)機(jī),并顯示狀態(tài)機(jī)當(dāng)前狀態(tài)及狀態(tài)間的轉(zhuǎn)移過程。我使用了Stateless開源類庫及一個(gè)開源自定義箭頭控件。自定義箭頭控件是HZHControls其中一個(gè)控件,我單獨(dú)把它從源碼中獨(dú)立出來。主要對代碼做了以下改動:
- 添加、刪除、替換了一部分注釋。
- 更改了一些內(nèi)部事件觸發(fā)邏輯,時(shí)間長了忘了具體改了什么,但不會影響主體功能。
- 在 protected override void OnPaint(PaintEventArgs e) 中內(nèi)聯(lián)了外部依賴的 public static void SetGDIHigh(Graphics g) 函數(shù),我在原作者博客的評論下有說明。
以上涉及到的相關(guān)項(xiàng)目的鏈接如下
自定義箭頭控件的代碼很有學(xué)習(xí)價(jià)值,可以在其基礎(chǔ)上擴(kuò)展出其它形狀的控件。使用時(shí)新建一個(gè)用戶控件然后復(fù)制代碼即可,代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
namespace ExtControls
{
public partial class Arrow : UserControl
{
private Color arrowColor = Color.DarkGray;
/// <summary>
/// 獲取設(shè)置箭頭顏色
/// </summary>
[Description("箭頭顏色"), Category("自定義")]
public Color ArrowColor
{
get { return arrowColor; }
set
{
arrowColor = value;
Refresh();
}
}
private Color? borderColor = null;
/// <summary>
/// 獲取或設(shè)置箭頭邊框顏色
/// </summary>
[Description("箭頭邊框顏色,為空則無邊框"), Category("自定義")]
public Color? BorderColor
{
get { return borderColor; }
set
{
borderColor = value;
Refresh();
}
}
/// <summary>
/// 箭頭方向
/// </summary>
private ArrowDirection direction = ArrowDirection.Right;
/// <summary>
/// 獲取或設(shè)置箭頭方向
/// </summary>
/// <value>The direction.</value>
[Description("獲取或設(shè)置箭頭方向"), Category("自定義")]
public ArrowDirection Direction
{
get { return direction; }
set
{
direction = value;
ResetMyPath();
Refresh();
}
}
private string text;
/// <summary>
/// 與控件關(guān)聯(lián)的文本。
/// </summary>
[Bindable(true)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[EditorBrowsable(EditorBrowsableState.Always)]
[Localizable(true)]
[Description("與控件關(guān)聯(lián)的文本"), Category("自定義")]
public override string Text
{
get
{
return text;
}
set
{
text = value;
Refresh();
}
}
/// <summary>
/// 圖形空間
/// </summary>
GraphicsPath myPath;
/// <summary>
/// 初始化UCArrow類的新實(shí)例。
/// </summary>
public Arrow()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.ForeColor = Color.White;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.SizeChanged += UCArrow_NeedResetChanged;
this.Size = new Size(100, 50);
this.ForeColorChanged += UCArrow_NeedResetChanged;
this.ForeColor = Color.Black;
this.FontChanged += UCArrow_NeedResetChanged;
}
/// <summary>
/// 需要重繪控件的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void UCArrow_NeedResetChanged(object sender, EventArgs e)
{
ResetMyPath();
}
/// <summary>
/// 重置圖形
/// </summary>
private void ResetMyPath()
{
Point[] ps = null;
switch (direction)
{
case ArrowDirection.Left:
ps = new Point[]
{
new Point(0,this.Height/2),
new Point(40,0),
new Point(40,this.Height/4),
new Point(this.Width-1,this.Height/4),
new Point(this.Width-1,this.Height-this.Height/4),
new Point(40,this.Height-this.Height/4),
new Point(40,this.Height),
new Point(0,this.Height/2)
};
break;
case ArrowDirection.Right:
ps = new Point[]
{
new Point(0,this.Height/4),
new Point(this.Width-40,this.Height/4),
new Point(this.Width-40,0),
new Point(this.Width-1,this.Height/2),
new Point(this.Width-40,this.Height),
new Point(this.Width-40,this.Height-this.Height/4),
new Point(0,this.Height-this.Height/4),
new Point(0,this.Height/4)
};
break;
case ArrowDirection.Top:
ps = new Point[]
{
new Point(this.Width/2,0),
new Point(this.Width,40),
new Point(this.Width-this.Width/4,40),
new Point(this.Width-this.Width/4,this.Height-1),
new Point(this.Width/4,this.Height-1),
new Point(this.Width/4,40),
new Point(0,40),
new Point(this.Width/2,0),
};
break;
case ArrowDirection.Bottom:
ps = new Point[]
{
new Point(this.Width-this.Width/4,0),
new Point(this.Width-this.Width/4,this.Height-40),
new Point(this.Width,this.Height-40),
new Point(this.Width/2,this.Height-1),
new Point(0,this.Height-40),
new Point(this.Width/4,this.Height-40),
new Point(this.Width/4,0),
new Point(this.Width-this.Width/4,0),
};
break;
case ArrowDirection.Left_Right:
ps = new Point[]
{
new Point(0,this.Height/2),
new Point(40,0),
new Point(40,this.Height/4),
new Point(this.Width-40,this.Height/4),
new Point(this.Width-40,0),
new Point(this.Width-1,this.Height/2),
new Point(this.Width-40,this.Height),
new Point(this.Width-40,this.Height-this.Height/4),
new Point(40,this.Height-this.Height/4),
new Point(40,this.Height),
new Point(0,this.Height/2),
};
break;
case ArrowDirection.Top_Bottom:
ps = new Point[]
{
new Point(this.Width/2,0),
new Point(this.Width,40),
new Point(this.Width-this.Width/4,40),
new Point(this.Width-this.Width/4,this.Height-40),
new Point(this.Width,this.Height-40),
new Point(this.Width/2,this.Height-1),
new Point(0,this.Height-40),
new Point(this.Width/4,this.Height-40),
new Point(this.Width/4,40),
new Point(0,40),
new Point(this.Width/2,0),
};
break;
}
myPath = new GraphicsPath();
myPath.AddLines(ps);
myPath.CloseAllFigures();
}
/// <summary>
/// 引發(fā)Control.Paint 事件。
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var g = e.Graphics;
// 設(shè)置GDI高質(zhì)量模式抗鋸齒
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
g.FillPath(new SolidBrush(arrowColor), myPath);
if (borderColor != null && borderColor != Color.Empty)
g.DrawPath(new Pen(new SolidBrush(borderColor.Value)), myPath);
if (!string.IsNullOrEmpty(text))
{
var size = g.MeasureString(Text, Font);
g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF((this.Width - size.Width) / 2, (this.Height - size.Height) / 2));
}
}
}
/// <summary>
/// 箭頭方向的描述枚舉
/// </summary>
public enum ArrowDirection
{
/// <summary>
/// 向左
/// </summary>
Left,
/// <summary>
/// 向右
/// </summary>
Right,
/// <summary>
/// 向上
/// </summary>
Top,
/// <summary>
/// 向下
/// </summary>
Bottom,
/// <summary>
/// 向左向右
/// </summary>
Left_Right,
/// <summary>
/// 向上向下
/// </summary>
Top_Bottom
}
}
|