C#中Winform 实现Ajax效果自定义按钮

技术看点

  1.  WinForm自定义控件的使用
  2. 自定义控件gif动画的播放

需求及效果

又来一波 C# GDI自定义控件show 。这个控件已经使用几年了,最近找出来重构一下。原来是没有边框的,那么导致导航的功能不是很突出。本来想加个效果:在执行单击时显示Loading动画,在执行完单击事件后恢复原样。这就是网页里见到的局部刷新,Ajax常用的场景。需求来自几年前一个智能储物柜项目,人机界面有个美工设计好的效果图,为了省事和通用,需要一个透明的按钮来实现导航的任务。就是控件只是设计时可见,运行时不可见。

 

关键点说明

1)、GraphicsPath实现矩形的圆角羽化处理

using (GraphicsPath path = new GraphicsPath())

{

#region 羽化,圆角处理

path.StartFigure();

path.AddArc(new Rectangle(new Point(rect.X, rect.Y), new Size(2 * Radius, 2 * Radius)), 180, 90);

path.AddLine(new Point(rect.X + Radius, rect.Y), new Point(rect.Right - Radius, rect.Y));

path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Y), new Size(2 * Radius, 2 * Radius)), 270, 90);

path.AddLine(new Point(rect.Right, rect.Y + Radius), new Point(rect.Right, rect.Bottom - Radius));

path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 0, 90);

path.AddLine(new Point(rect.Right - Radius, rect.Bottom), new Point(rect.X + Radius, rect.Bottom));

path.AddArc(new Rectangle(new Point(rect.X, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 90, 90);

path.AddLine(new Point(rect.X, rect.Bottom - Radius), new Point(rect.X, rect.Y + Radius));

path.CloseFigure();

#endregion

要点就是画几段弧线和矩形连接起来。透明就是用了Color.FromArgb加上透明度,然后填充GraphicsPath形成透明区域。

g.FillPath(new SolidBrush(Color.FromArgb(153, BackColor)), path);

2)、单窗体应用如何模块化 

窗体只有一个,但操作界面好多个,由于是无人值守的应用。那么老是切换窗体操作是非常不方便的。工作区域是一个容器Panel,把每个操作界面定义成一个Panel作为只容器。

public partial class DepositBizPanel : UserControl

{

private BackgroundStyle backgroundStyle = BackgroundStyle.Green;

/// <summary>

/// 主题风格

/// </summary>

public BackgroundStyle BackgroundStyle

{

get { return backgroundStyle; }

set

{

backgroundStyle = value;

switch (value)

{

case GreenlandExpressBox.BackgroundStyle.Blue:

BackgroundImage = Properties.Resources.jbblue;

break;

case GreenlandExpressBox.BackgroundStyle.Orange:

BackgroundImage = Properties.Resources.jborange;

break;

case GreenlandExpressBox.BackgroundStyle.Green:

BackgroundImage = Properties.Resources.jbgreen;

break;

}

Invalidate();

}

}

public Panel ParentPanel

{

get;

set;

}

public Bitmap QR_Barcode

{

get { return (Bitmap)pbxBarcode.Image; }

set { pbxBarcode.Image = value; }

}

public DialogResult PanelDiagResult

{

get;

set;

}

public DepositBizPanel(Panel parent, Bitmap barcode, BackgroundStyle style)

{

InitializeComponent();

DoubleBuffered = true;

ParentPanel = parent;

QR_Barcode = barcode;

BackgroundStyle = style;

}

private void btnback_Click(object sender, EventArgs e)

{

foreach (Control panel in ParentPanel.Controls)

{

if (panel is DepositBizPanel)

{

ParentPanel.Controls.Remove(panel);

PanelDiagResult = DialogResult.Cancel;

break;

}

}

}

private void btnprocessnext_Click(object sender, EventArgs e)

{

foreach (Control panel in ParentPanel.Controls)

{

if (panel is DepositBizPanel)

{

ParentPanel.Controls.Remove(panel);

PanelDiagResult = DialogResult.OK;

break;

}

}

}

}

人机操作界面例子

 3)、控件播放gif动画

private void BeginAnimate()

{

if (m_AnimateImage == null)

return;

if (ImageAnimator.CanAnimate(m_AnimateImage))

{

//当gif动画每隔一定时间后,都会变换一帧,那么就会触发一事件,

//该方法就是将当前image每变换一帧时,都会调用当前这个委托所关联的方法。

ImageAnimator.Animate(m_AnimateImage, m_evthdlAnimator);

}

}

private void StopAnimate()

{

if (m_AnimateImage == null)

return;

try

{

if (ImageAnimator.CanAnimate(m_AnimateImage))

{

ImageAnimator.StopAnimate(m_AnimateImage, m_evthdlAnimator);

}

}

finally

{

m_IsExecuted = false;

}

}

private void UpdateImage()

{

if (m_AnimateImage == null)

return;

if (ImageAnimator.CanAnimate(m_AnimateImage))

{

//获得当前gif动画的下一步需要渲染的帧,当下一步任何对当前gif动画的操作都是对该帧进行操作)

ImageAnimator.UpdateFrames(m_AnimateImage);

}

}

private void OnImageAnimate(Object sender, EventArgs e)

{

Invalidate();

}

protected override void OnLoad(EventArgs e)

{

base.OnLoad(e);

string s1 = @"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";

byte[] buffer = Convert.FromBase64String(s1);

MemoryStream ms = new MemoryStream(buffer);

var srcImg = Image.FromStream(ms);

m_AnimateImage = srcImg;

}

OnLoad执行的操作是从base64字符串里反序列化图片,就是效果图中的Loading的gif图片。这里遇到一个问题:在关闭了MemoryStream之后,会出现“gdi+ 中发生一般性错误”,于是改为不关闭了,控件销毁之后占用的内存就会释放吧。这是一点隐忧,如果有好的办法,希望留言告知。

透明按钮自定义控件全部代码

第一版自定义按钮:

/// <summary>

/// Cool透明自定义按钮

/// </summary>

public partial class CoolTransparentButton : UserControl

{

private Size iconSize = new Size(32, 32);

public Size IconSize

{

get

{

return iconSize;

}

set

{

iconSize = value;

Invalidate();

}

}

private string _ButtonText;

public string ButtonText

{

get { return _ButtonText; }

set

{

_ButtonText = value;

Invalidate();

}

}

protected Image _IconImage;

public Image IconImage

{

get

{

return _IconImage;

}

set

{

_IconImage = value;

Invalidate();

}

}

private bool _FocseActived = false;

private Color _BorderColor = Color.White;

public Color BorderColor

{

get

{

return _BorderColor;

}

set

{

_BorderColor = value;

Invalidate();

}

}

private int _Radius = 12;

public int Radius

{

get

{

return _Radius;

}

set

{

_Radius = value;

Invalidate();

}

}

private bool ifDrawBorderWhenLostFocse = true;

/// <summary>

/// 失去焦点是否画边框

/// </summary>

public bool IfDrawBorderWhenLostFocse

{

get

{

return ifDrawBorderWhenLostFocse;

}

set

{

ifDrawBorderWhenLostFocse = value;

Invalidate();

}

}

/// <summary>

/// 是否处于激活状态(焦点)

/// </summary>

public bool FocseActived

{

get { return _FocseActived; }

set

{

_FocseActived = value;

Invalidate();

}

}

public CoolTransparentButton()

{

DoubleBuffered = true;

BackColor = Color.Transparent;

SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);

SetStyle(ControlStyles.Opaque, false);

UpdateStyles();

}

protected override void OnPaint(PaintEventArgs e)

{

var rect = ClientRectangle;

rect.Inflate(-1, -1);

Graphics g = e.Graphics;

g.SmoothingMode = SmoothingMode.HighQuality;

using (GraphicsPath path = new GraphicsPath())

{

#region 羽化,圆角处理

path.StartFigure();

path.AddArc(new Rectangle(new Point(rect.X, rect.Y), new Size(2 * Radius, 2 * Radius)), 180, 90);

path.AddLine(new Point(rect.X + Radius, rect.Y), new Point(rect.Right - Radius, rect.Y));

path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Y), new Size(2 * Radius, 2 * Radius)), 270, 90);

path.AddLine(new Point(rect.Right, rect.Y + Radius), new Point(rect.Right, rect.Bottom - Radius));

path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 0, 90);

path.AddLine(new Point(rect.Right - Radius, rect.Bottom), new Point(rect.X + Radius, rect.Bottom));

path.AddArc(new Rectangle(new Point(rect.X, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 90, 90);

path.AddLine(new Point(rect.X, rect.Bottom - Radius), new Point(rect.X, rect.Y + Radius));

path.CloseFigure();

#endregion

if (!FocseActived)

{

if (ifDrawBorderWhenLostFocse)

g.DrawPath(new Pen(Color.Gray, 1), path);

g.FillPath(new SolidBrush(Color.FromArgb(66, BackColor)), path);

}

else

{

g.DrawPath(new Pen(BorderColor, 1), path);

rect.Inflate(-1, -1);

g.FillPath(new SolidBrush(Color.FromArgb(153, BackColor)), path);

}

#region 画文本

g.SmoothingMode = SmoothingMode.AntiAlias;

if (IconImage != null)

{

Rectangle rc = new Rectangle((Width - 32) / 2, 16, IconSize.Width, IconSize.Height);

g.DrawImage(IconImage, rc);

}

if (!string.IsNullOrEmpty(ButtonText))

{

using (StringFormat f = new StringFormat())

{

Rectangle rectTxt = new Rectangle(0, (Height - 18) / 2, Width, 36);

f.Alignment = StringAlignment.Center;// 水平居中对齐

f.LineAlignment = StringAlignment.Center; // 垂直居中对齐

f.FormatFlags = StringFormatFlags.NoWrap;// 设置为单行文本

SolidBrush fb = new SolidBrush(this.ForeColor); // 绘制文本

e.Graphics.DrawString(ButtonText, new Font("微软雅黑", 16F, FontStyle.Bold), fb, rectTxt, f);

}

}

#endregion

}

}

protected override void OnMouseHover(EventArgs e)

{

FocseActived = true;

}

protected override void OnMouseLeave(EventArgs e)

{

FocseActived = false;

}

protected override void OnEnter(EventArgs e)

{

FocseActived = true;

}

protected override void OnLeave(EventArgs e)

{

FocseActived = false;

}

}

第二版自定义按钮:

/// <summary>

/// 自定义透明自定义按钮,模仿实现了网页元素的Ajax效果

/// </summary>

public partial class AjaxTransparentButton : UserControl

{

private Size iconSize = new Size(32, 32);

public Size IconSize

{

get

{

return iconSize;

}

set

{

iconSize = value;

Invalidate();

}

}

private string _ButtonText;

public string ButtonText

{

get { return _ButtonText; }

set

{

_ButtonText = value;

Invalidate();

}

}

protected Image _IconImage;

public Image IconImage

{

get

{

return _IconImage;

}

set

{

_IconImage = value;

Invalidate();

}

}

private bool _FocseActived = false;

private Color _BorderColor = Color.White;

public Color BorderColor

{

get

{

return _BorderColor;

}

set

{

_BorderColor = value;

Invalidate();

}

}

private int _Radius = 12;

public int Radius

{

get

{

return _Radius;

}

set

{

_Radius = value;

Invalidate();

}

}

private bool ifDrawBorderWhenLostFocse = true;

/// <summary>

/// 失去焦点是否画边框

/// </summary>

public bool IfDrawBorderWhenLostFocse

{

get

{

return ifDrawBorderWhenLostFocse;

}

set

{

ifDrawBorderWhenLostFocse = value;

Invalidate();

}

}

/// <summary>

/// 是否处于激活状态(焦点)

/// </summary>

public bool FocseActived

{

get { return _FocseActived; }

set

{

_FocseActived = value;

Invalidate();

}

}

private Image m_AnimateImage = null;

private EventHandler m_evthdlAnimator = null;

private bool m_IsExecuted = false;

public AjaxTransparentButton()

{

BackColor = Color.Transparent;

SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);

SetStyle(ControlStyles.Opaque, false);

UpdateStyles();

m_evthdlAnimator = new EventHandler(OnImageAnimate);

}

protected override void OnPaint(PaintEventArgs e)

{

var rect = ClientRectangle;

rect.Inflate(-1, -1);

Graphics g = e.Graphics;

g.SmoothingMode = SmoothingMode.HighQuality;

using (GraphicsPath path = new GraphicsPath())

{

#region 羽化,圆角处理

path.StartFigure();

path.AddArc(new Rectangle(new Point(rect.X, rect.Y), new Size(2 * Radius, 2 * Radius)), 180, 90);

path.AddLine(new Point(rect.X + Radius, rect.Y), new Point(rect.Right - Radius, rect.Y));

path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Y), new Size(2 * Radius, 2 * Radius)), 270, 90);

path.AddLine(new Point(rect.Right, rect.Y + Radius), new Point(rect.Right, rect.Bottom - Radius));

path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 0, 90);

path.AddLine(new Point(rect.Right - Radius, rect.Bottom), new Point(rect.X + Radius, rect.Bottom));

path.AddArc(new Rectangle(new Point(rect.X, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 90, 90);

path.AddLine(new Point(rect.X, rect.Bottom - Radius), new Point(rect.X, rect.Y + Radius));

path.CloseFigure();

#endregion

if (!FocseActived)

{

if (ifDrawBorderWhenLostFocse)

g.DrawPath(new Pen(Color.Gray, 1), path);

g.FillPath(new SolidBrush(Color.FromArgb(66, BackColor)), path);

}

else

{

g.DrawPath(new Pen(BorderColor, 1), path);

rect.Inflate(-1, -1);

g.FillPath(new SolidBrush(Color.FromArgb(153, BackColor)), path);

}

#region 画文本

g.SmoothingMode = SmoothingMode.AntiAlias;

if (IconImage != null)

{

Rectangle rc = new Rectangle((Width - 32) / 2, 16, IconSize.Width, IconSize.Height);

g.DrawImage(IconImage, rc);

}

if (!string.IsNullOrEmpty(ButtonText))

{

using (StringFormat f = new StringFormat())

{

Rectangle rectTxt = new Rectangle(0, (Height - 18) / 2, Width, 36);

f.Alignment = StringAlignment.Center;// 水平居中对齐

f.LineAlignment = StringAlignment.Center; // 垂直居中对齐

f.FormatFlags = StringFormatFlags.NoWrap;// 设置为单行文本

SolidBrush fb = new SolidBrush(this.ForeColor); // 绘制文本

e.Graphics.DrawString(ButtonText, new Font("微软雅黑", 16F, FontStyle.Bold), fb, rectTxt, f);

}

}

if (m_AnimateImage != null)

{

Rectangle rectGif = new Rectangle((Width - 24) / 2, (Height - 16) / 2 - 8, 32, 32);

if (m_IsExecuted)

{

UpdateImage();

e.Graphics.DrawImage(m_AnimateImage, rectGif);

}

else

{

e.Graphics.FillRectangle(new SolidBrush(Color.Transparent), rectGif);

}

}

#endregion

}

}

protected override void OnMouseHover(EventArgs e)

{

FocseActived = true;

}

protected override void OnMouseLeave(EventArgs e)

{

FocseActived = false;

}

protected override void OnEnter(EventArgs e)

{

FocseActived = true;

}

protected override void OnLeave(EventArgs e)

{

FocseActived = false;

}

private void BeginAnimate()

{

if (m_AnimateImage == null)

return;

if (ImageAnimator.CanAnimate(m_AnimateImage))

{

//当gif动画每隔一定时间后,都会变换一帧,那么就会触发一事件,

//该方法就是将当前image每变换一帧时,都会调用当前这个委托所关联的方法。

ImageAnimator.Animate(m_AnimateImage, m_evthdlAnimator);

}

}

private void StopAnimate()

{

if (m_AnimateImage == null)

return;

try

{

if (ImageAnimator.CanAnimate(m_AnimateImage))

{

ImageAnimator.StopAnimate(m_AnimateImage, m_evthdlAnimator);

}

}

finally

{

m_IsExecuted = false;

}

}

private void UpdateImage()

{

if (m_AnimateImage == null)

return;

if (ImageAnimator.CanAnimate(m_AnimateImage))

{

//获得当前gif动画的下一步需要渲染的帧,当下一步任何对当前gif动画的操作都是对该帧进行操作)

ImageAnimator.UpdateFrames(m_AnimateImage);

}

}

private void OnImageAnimate(Object sender, EventArgs e)

{

Invalidate();

}

protected override void OnLoad(EventArgs e)

{

base.OnLoad(e);

string s1 = @"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";

byte[] buffer = Convert.FromBase64String(s1);

MemoryStream ms = new MemoryStream(buffer);

var srcImg = Image.FromStream(ms);

m_AnimateImage = srcImg;

}

protected override void OnClick(EventArgs e)

{

if (m_IsExecuted)

return;

Action clickTask = () =>

{

m_IsExecuted = true;

BeginAnimate();

base.OnClick(e);

Invalidate();

};

//异步执行单击事件

clickTask.BeginInvoke((result) =>

{

clickTask.EndInvoke(result);

m_IsExecuted = false;

StopAnimate();

}, null);

}

protected override void Dispose(bool disposing)

{

base.Dispose(disposing);

if (m_AnimateImage != null)

{

try

{

StopAnimate();

}

finally

{

m_AnimateImage.Dispose();

m_evthdlAnimator = null;

}

}

}

protected override void OnKeyDown(KeyEventArgs e)

{

base.OnKeyDown(e);

if (e.KeyCode == Keys.Enter)

{

OnClick(e);

}

}

}

注释不是很多,源码如有需要拿走不谢

以上是 C#中Winform 实现Ajax效果自定义按钮 的全部内容, 来源链接: utcz.com/z/351043.html

回到顶部