标签:npoi art smooth lse sem one rap http wing
///
/// 图案滑屏解锁控件
///
[ToolboxItem(true)]
[DefaultEvent("UnLock")]
[DefaultProperty("Value")]
[Description("图案滑屏解锁控件")]
public partial class PatternLockExt : Control
{
#region 事件
public delegate void PatternLockEventHandler(object sender, PatternLockEventArgs e);
private event PatternLockEventHandler unLock;
///
/// 图案滑屏解锁事件
///
[Description("图案滑屏解锁事件")]
public event PatternLockEventHandler UnLock
{
add { this.unLock += value; }
remove { this.unLock -= value; }
}
#endregion
#region 属性
private PatternLockTypes type = PatternLockTypes.Valid;
///
/// 功能类型
///
[DefaultValue(PatternLockTypes.Valid)]
[Description("功能类型")]
public PatternLockTypes Type
{
get { return this.type; }
set
{
if (this.type == value)
return;
this.type = value;
this.Invalidate();
}
}
private PatternLockItemTypes unLockType = PatternLockItemTypes.Pattern;
///
/// 解锁类型
///
[DefaultValue(PatternLockItemTypes.Pattern)]
[Description("解锁类型")]
public PatternLockItemTypes UnLockType
{
get { return this.unLockType; }
set
{
if (this.unLockType == value)
return;
this.unLockType = value;
this.Invalidate();
}
}
private bool showLine = true;
///
/// 显示解锁路径
///
[DefaultValue(true)]
[Description("显示解锁路径")]
public bool ShowLine
{
get { return this.showLine; }
set
{
if (this.showLine == value)
return;
this.showLine = value;
this.Invalidate();
}
}
private string value = "";
///
/// 解锁正确值
///
[DefaultValue("")]
[Description("解锁正确值")]
public string Value
{
get { return this.value; }
set
{
if (this.value == value)
return;
this.value = value;
}
}
private Font unLockFont = new Font("宋体", 20f);
///
/// 解锁数字字体
///
[DefaultValue(typeof(Font), "宋体, 20pt")]
[Description("解锁数字字体")]
public Font UnLockFont
{
get { return this.unLockFont; }
set
{
if (this.unLockFont == value)
return;
this.unLockFont = value;
this.Invalidate();
}
}
private Color normalColor = Color.FromArgb(255, 255, 255);
///
/// 解锁颜色(正常)
///
[DefaultValue(typeof(Color), "255, 255, 255")]
[Description("解锁颜色(正常)")]
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public Color NormalColor
{
get { return this.normalColor; }
set
{
if (this.normalColor == value)
return;
this.normalColor = value;
this.Invalidate();
}
}
private Color passColor = Color.FromArgb(153, 204, 153);
///
/// 解锁颜色(通过)
///
[DefaultValue(typeof(Color), "153, 204, 153")]
[Description("解锁颜色(通过)")]
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public Color PassColor
{
get { return this.passColor; }
set
{
if (this.passColor == value)
return;
this.passColor = value;
this.Invalidate();
}
}
private Color errorColor = Color.FromArgb(255, 128, 128);
///
/// 解锁颜色(错误)
///
[DefaultValue(typeof(Color), "255, 128, 128")]
[Description("解锁颜色(错误)")]
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public Color ErrorColor
{
get { return this.errorColor; }
set
{
if (this.errorColor == value)
return;
this.errorColor = value;
this.Invalidate();
}
}
///
/// 重写背景颜色
///
[DefaultValue(typeof(Color), "64, 64, 64")]
[Description("内圆背景颜色(正常)")]
[Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
public override Color BackColor
{
get
{
return base.BackColor;
}
set
{
base.BackColor = value;
}
}
///
/// 重写默认Size
///
[Description("重写默认Size")]
protected override Size DefaultSize
{
get
{
return new Size(300, 300);
}
}
///
/// 鼠标是否按下
///
private bool moveDown = false;
///
/// 鼠标按下坐标
///
private Point moveDownPoint = Point.Empty;
///
/// 解锁状态
///
private PatternLockStatus unLockStatus = PatternLockStatus.Normal;
///
/// 选中解锁选项
///
private Dictionaryint, string> selectList = new Dictionaryint, string>();
///
/// 解锁选项列表
///
private List unLockItemList = new List() {
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="1"},
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="2"},
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="3"},
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="4"},
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="5"},
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="6"},
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="7"},
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="8"},
new PatternLockItem(){ out_rectf= RectangleF.Empty, gp=new GraphicsPath(), status= PatternLockItemStatus.Normal, value="9"},
};
#endregion
public PatternLockExt()
{
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.FromArgb(64, 64, 64);
InitializeComponent();
this.InitializeJigsawDisplay();
this.Invalidate();
}
#region 重写
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
StringFormat sf = (this.UnLockType == PatternLockItemTypes.Pattern) ? null : new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
#region
if (!this.ShowLine)
{
SolidBrush Normal_sb_inBackColor = new SolidBrush(this.NormalColor);
for (int i = 0; i this.unLockItemList.Count; i++)
{
if (this.UnLockType == PatternLockItemTypes.Pattern)
{
g.FillEllipse(Normal_sb_inBackColor, this.unLockItemList[i].in_rectf);
}
else
{
g.DrawString(this.unLockItemList[i].value, this.UnLockFont, Normal_sb_inBackColor, this.unLockItemList[i].out_rectf, sf);
}
}
Normal_sb_inBackColor.Dispose();
}
#endregion
#region
else
{
#region 画笔
float lineSize = this.unLockItemList[0].in_rectf.Width;
SolidBrush Normal_sb_inBackColor = new SolidBrush(this.NormalColor);
SolidBrush Normal_sb_outBackColor = new SolidBrush(Color.FromArgb(50, this.NormalColor));
Pen Normal_pen_outLineColor = new Pen(this.NormalColor, lineSize / 3f);
Normal_pen_outLineColor.Alignment = PenAlignment.Outset;
Pen Normal_pen_lineColor = new Pen(Color.FromArgb(150, this.NormalColor), lineSize);
Normal_pen_lineColor.Alignment = PenAlignment.Center;
Normal_pen_lineColor.StartCap = LineCap.Round;
Normal_pen_lineColor.EndCap = LineCap.Round;
SolidBrush Pass_sb_inBackColor = null;
SolidBrush Pass_sb_outBackColor = null;
Pen Pass_pen_outLineColor = null;
Pen Pass_pen_lineColor = null;
if (this.unLockStatus == PatternLockStatus.Pass)
{
Pass_sb_inBackColor = new SolidBrush(this.PassColor);
Pass_sb_outBackColor = new SolidBrush(Color.FromArgb(50, this.PassColor));
Pass_pen_outLineColor = new Pen(this.PassColor, lineSize / 3f);
Pass_pen_outLineColor.Alignment = PenAlignment.Outset;
Pass_pen_lineColor = new Pen(Color.FromArgb(150, this.PassColor), lineSize);
Pass_pen_lineColor.Alignment = PenAlignment.Center;
Pass_pen_lineColor.StartCap = LineCap.Round;
Pass_pen_lineColor.EndCap = LineCap.Round;
}
SolidBrush Error_sb_inBackColor = null;
SolidBrush Error_sb_outBackColor = null;
Pen Error_pen_outLineColor = null;
Pen Error_pen_lineColor = null;
if (this.unLockStatus == PatternLockStatus.Error)
{
Error_sb_inBackColor = new SolidBrush(this.ErrorColor);
Error_sb_outBackColor = new SolidBrush(Color.FromArgb(50, this.ErrorColor));
Error_pen_outLineColor = new Pen(this.ErrorColor, lineSize / 3f);
Error_pen_outLineColor.Alignment = PenAlignment.Outset;
Error_pen_lineColor = new Pen(Color.FromArgb(150, this.ErrorColor), lineSize);
Error_pen_lineColor.Alignment = PenAlignment.Center;
Error_pen_lineColor.StartCap = LineCap.Round;
Error_pen_lineColor.EndCap = LineCap.Round;
}
#endregion
#region 绘制
switch (this.unLockStatus)
{
case PatternLockStatus.Normal:
{
#region
for (int i = 0; i this.unLockItemList.Count; i++)
{
if (this.UnLockType == PatternLockItemTypes.Pattern)
{
g.FillEllipse(Normal_sb_inBackColor, this.unLockItemList[i].in_rectf);
}
else
{
g.DrawString(this.unLockItemList[i].value, this.UnLockFont, Normal_sb_inBackColor, this.unLockItemList[i].out_rectf, sf);
}
}
break;
#endregion
}
case PatternLockStatus.UnLock:
case PatternLockStatus.Finish:
{
#region
for (int i = 0; i this.unLockItemList.Count; i++)
{
if (this.unLockItemList[i].status == PatternLockItemStatus.Select)
{
g.FillEllipse(Normal_sb_outBackColor, this.unLockItemList[i].out_rectf);
g.DrawEllipse(Normal_pen_outLineColor, this.unLockItemList[i].out_rectf);
}
if (this.UnLockType == PatternLockItemTypes.Pattern)
{
g.FillEllipse(Normal_sb_inBackColor, this.unLockItemList[i].in_rectf);
}
else
{
g.DrawString(this.unLockItemList[i].value, this.UnLockFont, Normal_sb_inBackColor, this.unLockItemList[i].out_rectf, sf);
}
}
this.DrawUnLockLine(g, Normal_pen_lineColor);
break;
#endregion
}
case PatternLockStatus.Pass:
{
#region
for (int i = 0; i this.unLockItemList.Count; i++)
{
if (this.unLockItemList[i].status == PatternLockItemStatus.Select)
{
g.FillEllipse(Pass_sb_outBackColor, this.unLockItemList[i].out_rectf);
g.DrawEllipse(Pass_pen_outLineColor, this.unLockItemList[i].out_rectf);
if (this.UnLockType == PatternLockItemTypes.Pattern)
{
g.FillEllipse(Pass_sb_inBackColor, this.unLockItemList[i].in_rectf);
}
else
{
g.DrawString(this.unLockItemList[i].value, this.UnLockFont, Pass_sb_inBackColor, this.unLockItemList[i].out_rectf, sf);
}
}
else
{
g.FillEllipse(Normal_sb_inBackColor, this.unLockItemList[i].in_rectf);
}
}
this.DrawUnLockLine(g, Pass_pen_lineColor);
break;
#endregion
}
case PatternLockStatus.Error:
{
#region
for (int i = 0; i this.unLockItemList.Count; i++)
{
if (this.unLockItemList[i].status == PatternLockItemStatus.Select)
{
g.FillEllipse(Error_sb_outBackColor, this.unLockItemList[i].out_rectf);
g.DrawEllipse(Error_pen_outLineColor, this.unLockItemList[i].out_rectf);
if (this.UnLockType == PatternLockItemTypes.Pattern)
{
g.FillEllipse(Error_sb_inBackColor, this.unLockItemList[i].in_rectf);
}
else
{
g.DrawString(this.unLockItemList[i].value, this.UnLockFont, Error_sb_inBackColor, this.unLockItemList[i].out_rectf, sf);
}
}
else
{
g.FillEllipse(Normal_sb_inBackColor, this.unLockItemList[i].in_rectf);
}
}
this.DrawUnLockLine(g, Error_pen_lineColor);
break;
#endregion
}
}
#endregion
#region 释放
if (Normal_sb_inBackColor != null)
Normal_sb_inBackColor.Dispose();
if (Normal_sb_outBackColor != null)
Normal_sb_outBackColor.Dispose();
if (Normal_pen_outLineColor != null)
Normal_pen_outLineColor.Dispose();
if (Normal_pen_lineColor != null)
Normal_pen_lineColor.Dispose();
if (Pass_sb_inBackColor != null)
Pass_sb_inBackColor.Dispose();
if (Pass_sb_outBackColor != null)
Pass_sb_outBackColor.Dispose();
if (Pass_pen_outLineColor != null)
Pass_pen_outLineColor.Dispose();
if (Pass_pen_lineColor != null)
Pass_pen_lineColor.Dispose();
if (Error_sb_inBackColor != null)
Error_sb_inBackColor.Dispose();
if (Error_sb_outBackColor != null)
Error_sb_outBackColor.Dispose();
if (Error_pen_outLineColor != null)
Error_pen_outLineColor.Dispose();
if (Error_pen_lineColor != null)
Error_pen_lineColor.Dispose();
#endregion
}
#endregion
if (sf != null)
sf.Dispose();
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (this.unLockStatus == PatternLockStatus.Normal)
{
this.moveDown = true;
this.unLockStatus = PatternLockStatus.UnLock;
for (int i = 0; i this.unLockItemList.Count; i++)
{
if (this.unLockItemList[i].gp.IsVisible(e.Location))
{
if (this.unLockItemList[i].status == PatternLockItemStatus.Normal)
{
this.unLockItemList[i].status = PatternLockItemStatus.Select;
this.selectList.Add(i, this.unLockItemList[i].value);
this.moveDownPoint = e.Location;
this.Invalidate();
break;
}
}
}
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
this.moveDown = false;
if (this.unLockStatus == PatternLockStatus.UnLock)
{
this.unLockStatus = PatternLockStatus.Finish;
if (this.selectList.Count > 0)
{
this.UnLockValid();
}
}
}
protected override void OnMouseLeave(EventArgs e)
{
this.moveDown = false;
if (this.unLockStatus == PatternLockStatus.UnLock)
{
this.unLockStatus = PatternLockStatus.Finish;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (this.moveDown)
{
if (this.unLockStatus == PatternLockStatus.UnLock)
{
for (int i = 0; i this.unLockItemList.Count; i++)
{
if (this.unLockItemList[i].gp.IsVisible(e.Location))
{
if (this.unLockItemList[i].status == PatternLockItemStatus.Normal)
{
this.unLockItemList[i].status = PatternLockItemStatus.Select;
this.selectList.Add(i, this.unLockItemList[i].value);
}
this.moveDownPoint = e.Location;
this.Invalidate();
return;
}
}
this.moveDownPoint = e.Location;
this.Invalidate();
}
}
}
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
base.SetBoundsCore(x, y, width, width, specified);
this.InitializeJigsawDisplay();
this.Invalidate();
}
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
///
/// 初始化解锁选项信息
///
protected void InitializeJigsawDisplay()
{
/*解锁圆形的直径自动计算方式(解锁圆形包括内圆、外圆、外圆边厚度)
1.解锁圆形的内圆直径=解锁圆形的外圆直径五分之一
2.解锁圆形之间间距=解锁圆形的外圆直径十分之七
3.解锁圆形的外圆边厚度=解锁圆形的内圆直径三分之一
控件工作区的矩形宽度=内边距*2+外圆直径*3+圆形之间间距*2+外圆边厚度*2
*/
float rect_width = (float)this.ClientRectangle.Width;
float draw_padding = 2f;//绘图区内边距
float draw_width = rect_width - draw_padding * 2f;//绘图区宽度
float circle_out_diameter = draw_width * 15f / 68f;//外圆直径 公式原型:rect_width=(draw_padding*2)+(circle_out_diameter*3)+(circle_out_diameter*0.7*2)+(circle_out_diameter/5/3*2)
float circle_in_diameter = circle_out_diameter / 5f;//内圆直径
float circle_interval = circle_out_diameter * 0.7f;//圆形间距
float circle_border = circle_out_diameter / (5f * 3f);//外圆边厚度
for (int x = 0; x 3; x++)
{
for (int y = 0; y 3; y++)
{
int index = x * 3 + y;
RectangleF out_rectf = new RectangleF(draw_padding + circle_border + y * circle_out_diameter + circle_interval * y, draw_padding + circle_border + x * circle_out_diameter + circle_interval * x, circle_out_diameter, circle_out_diameter);
RectangleF in_rectf = new RectangleF(out_rectf.Left + circle_in_diameter * 2f, out_rectf.Top + circle_in_diameter * 2f, circle_in_diameter, circle_in_diameter);
this.unLockItemList[index].out_rectf = out_rectf;
this.unLockItemList[index].in_rectf = in_rectf;
this.unLockItemList[index].pointf = new PointF(out_rectf.Left + out_rectf.Width / 2f, out_rectf.Top + out_rectf.Height / 2f);
this.unLockItemList[index].gp.Reset();
this.unLockItemList[index].gp.AddEllipse(out_rectf);
}
}
}
///
/// 绘制解锁路径线条
///
///
///
protected void DrawUnLockLine(Graphics g, Pen pen)
{
for (int j = 0; j this.selectList.Count - 1; j++)
{
g.DrawLine(pen, this.unLockItemList[this.selectList.ElementAt(j).Key].pointf, this.unLockItemList[this.selectList.ElementAt(j + 1).Key].pointf);
}
if (this.selectList.Count > 0 && this.unLockStatus == PatternLockStatus.UnLock)
{
g.DrawLine(pen, this.unLockItemList[this.selectList.ElementAt(this.selectList.Count - 1).Key].pointf, this.moveDownPoint);
}
}
///
/// 重置解锁
///
public void UnLockReset()
{
this.unLockStatus = PatternLockStatus.Normal;
this.selectList.Clear();
for (int i = 0; i this.unLockItemList.Count; i++)
{
this.unLockItemList[i].status = PatternLockItemStatus.Normal;
}
this.Invalidate();
}
///
/// 解锁验证
///
///
protected void UnLockValid()
{
string str = String.Concat(this.selectList.Values.ToListstring>());
PatternLockEventArgs data = new PatternLockEventArgs();
data.Value = str;
if (this.Type == PatternLockTypes.Valid)
{
data.Result = (this.Value == str);
this.unLockStatus = data.Result ? PatternLockStatus.Pass : PatternLockStatus.Error;
}
else
{
data.Result = true;
}
this.Invalidate();
if (this.unLock != null)
{
this.unLock(this, data);
}
}
///
/// 解锁事件参数
///
[Description("解锁事件参数")]
public class PatternLockEventArgs : EventArgs
{
///
/// 解锁验证结果
///
[Description("解锁结果")]
public bool Result { get; set; }
///
/// 解锁生成结果
///
[Description("解锁生成结果")]
public string Value { get; set; }
}
///
/// 解锁选项
///
[Description("解锁选项")]
public class PatternLockItem
{
///
/// 图案外rectf
///
public RectangleF out_rectf { get; set; }
///
/// 图案内rectf
///
public RectangleF in_rectf { get; set; }
///
/// 图案path
///
public GraphicsPath gp { get; set; }
///
/// 图案中心point
///
public PointF pointf { get; set; }
///
/// 图案选项状态
///
public PatternLockItemStatus status { get; set; }
///
/// 值
///
public string value { get; set; }
}
///
/// 解锁状态
///
[Description("解锁状态")]
public enum PatternLockStatus
{
///
/// 正常(默认)
///
Normal,
///
/// 解锁中
///
UnLock,
///
/// 完成中
///
Finish,
///
/// 通过
///
Pass,
///
/// 错误
///
Error
}
///
/// 解锁选项状态
///
[Description("解锁选项状态")]
public enum PatternLockItemStatus
{
///
/// 正常
///
Normal,
///
/// 选中
///
Select
}
///
/// 解锁类型
///
[Description("解锁类型")]
public enum PatternLockItemTypes
{
///
/// 数字
///
Number,
///
/// 图案
///
Pattern
}
///
/// 功能类型
///
[Description("功能类型")]
public enum PatternLockTypes
{
///
/// 验证
///
Valid,
///
/// 生成
///
Create
}
}
源码下载:图案滑屏解锁控件.zip
图案滑屏解锁控件----------WinForm控件开发系列
标签:npoi art smooth lse sem one rap http wing
原文地址:https://www.cnblogs.com/tlmbem/p/12902818.html