C#自定义控件
- 选择“解决方案”,右键-选择“添加”,选择“新建项目”,弹出对话框:
选择“窗体控件库”
- 新建的自定义控件,继承自那个控件,在新建的.cs文件中直接修改即可,如下如所示
namespace SplitContainer_EX { public partial class My_SP_EX : SplitContainer { public My_SP_EX() { //控件自定义-双缓冲设置1 this.SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); InitializeComponent(); } protected override CreateParams CreateParams//控件自定义-双缓冲设置2 { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } } } }
- 编译一下软件,在bin->debug文件夹中会生成.dll文件
- 选择“工具箱”,右键选择“选择项”,在“.NET Framework组件”中添加刚才生成的.dll文件即可
测试代码
private void Form1_Load(object sender, EventArgs e)
{
ScopeTimer = new System.Threading.Timer(new TimerCallback(Scope_TimerUpdateData_Elapsed), this, 0, 20);
this.SetStyle(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer, true);
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
void Scope_TimerUpdateData_Elapsed(object sender)//示波器采用的定时器用于更新显示或者发送测试数据的
{
Sin_test_Count++;
int temppp = (int)(Math.Sin(Sin_test_Count * 6.2830 / 360) * userControl11.Panel1.Height / 3);//splitContainer1.Panel1 userControl11
list.Add(temppp);
if (Sin_test_Count >= 360)
{
Sin_test_Count = 0;
}
this.BeginInvoke(new Action(() =>
{
userControl11.Panel1.Invalidate(true);
userControl11.Panel1.Update();
}), null);
}
//void DrawScreen(Image* image)
//{
// bitmap = (Bitmap*)image; //image转为bitmap
// bitmap->GetHBITMAP(Color(0, 0, 0), &hBitmap); //获取bitmap对应GDI位图句柄
// CDC* cdc = GetDC(); //创建目标dc
// HDC srchdc = CreateCompatibleDC(cdc->m_hDC); //创建源dc
// SelectObject(srchdc, hBitmap); //将源位图句柄选入源dc
// BitBlt(cdc->m_hDC, 0, 0, CLIENT_WIDTH, CLIENT_HEIGHT, srchdc, 0, 0, SRCCOPY);//绘图
// DeleteObject(hBitmap);
// DeleteDC(srchdc);
// ReleaseDC(cdc);
//}
private void userControl11_Panel1_Paint(object sender, PaintEventArgs e)
{
DateTime t = DateTime.Now;
Graphics g = e.Graphics;
// Graphics g = this.CreateGraphics();
Bitmap bmp = new Bitmap(userControl11.Panel1.Width, userControl11.Panel1.Height);
Graphics bufg = Graphics.FromImage(bmp);
//g.Clear(this.BackColor);//可用可不用,视具体情况
//bufg.Clear(this.BackColor);//可用可不用
//bufg.DrawLine(new Pen(Color.Black, 1), startP, endP);
//Graphics offScreenDC = Graphics.FromImage(bmp);
//Graphics ClientDC = e.Graphics;// this.CreateGraphics();
//ClientDC.SetClip(new RectangleF(0, 0, 600, 600));
//HDC hdc = ClientDC.GetHdc();
//memdc = GDI.CreateCompatibleDC(hdc);
//GDI.SelectObject(memdc, bitmap.GetHbitmap());
//Graphics memDC = Graphics.FromHdc(memdc);
if ((list.Count - 1) >= (userControl11.Panel1.Width))
{
list.RemoveRange(0, list.Count - userControl11.Panel1.Width - 1);
}
for (int i = 0; i < list.Count - 1; i++)//绘制
{
Point sp = new Point(i, userControl11.Panel1.Width / 6 + list[i]);
Point ep = new Point((i + 1), userControl11.Panel1.Width / 6 + list[i + 1]);
bufg.DrawLine(Pens.DarkGreen, sp, ep);
}
g.DrawImage(bmp, 0, 0);
bufg.Dispose();
bmp.Dispose();
DateTime t2 = DateTime.Now;
spppp = t2 - t;
float per = 1000 / spppp.Milliseconds;
this.label1.Text = "速度:" + per.ToString() + "帧/秒";
}
测试在窗体中是否增加双缓冲设置1和双缓冲设置2,以及在自定义的控件中是否增加双缓冲设置1和双缓冲设置2,验证对绘图刷新的速度。
在窗体放入一个自定义的SplitContainer控件,利用一个定时器产生Panel1的Paint事件,在Paint中绘图,观察绘图刷新的情况;分为以下几种情况验证
- 在窗体中设置双缓冲设置1和双缓冲设置2,以及自定义控件中设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:60-80帧/秒
- 在窗体中不设置双缓冲设置1和双缓冲设置2,以及自定义控件中设置双缓冲设置1和双缓冲设置2观察绘图刷新情况;
是否闪烁:不闪烁
刷新速度:40-70帧/秒
- 在窗体中仅仅设置双缓冲设置1,以及自定义控件中设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;
是否闪烁:不闪烁
刷新速度:40-70帧/秒
- 在窗体中仅仅设置双缓冲设置2,以及自定义控件中设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:60-70帧/秒
以上测试在自定义控件中增加双缓冲设置1和双缓冲设置2,只要不在窗体控件中增加双缓冲设置2就没有问题
- 在窗体中不设置双缓冲设置1和双缓冲设置2,以及自定义控件中不设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:20-30帧/秒
- 在窗体中设置双缓冲设置1或双缓冲设置2,以及自定义控件中不设置双缓冲设置1和双缓冲设置2,观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:20-110帧/秒
- 在窗体中设置双缓冲设置1或双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置1,观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:20-110帧/秒
- 在窗体中不设置双缓冲设置1和双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置1观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:帧/秒
- 在窗体中仅仅设置双缓冲设置1,以及自定义控件中仅仅设置双缓冲设置1观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:帧/秒
- 在窗体中仅仅设置双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置1观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:帧/秒
- 在窗体中设置双缓冲设置1或双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置2,观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:20-110帧/秒
- 在窗体中不设置双缓冲设置1和双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置2观察绘图刷新情况;
是否闪烁:不闪烁
刷新速度:50-80帧/秒
- 在窗体中仅仅设置双缓冲设置1,以及自定义控件中仅仅设置双缓冲设置2观察绘图刷新情况;
是否闪烁:不闪烁
刷新速度:60-110帧/秒
- 在窗体中仅仅设置双缓冲设置2,以及自定义控件中仅仅设置双缓冲设置2观察绘图刷新情况;
是否闪烁:闪烁
刷新速度:帧/秒
以上测试结论:
不闪烁的必须条件:在自定义控件中必须含有双缓冲设置2,窗体控件中不能含有双缓冲设置2既可;