vs 自绘控件--自绘多按钮控件
来源:互联网 发布:手机源码怎么用 编辑:程序博客网 时间:2024/06/10 19:10
最近的项目开发中,同事开发界面时遇到了这样的问题。在一个容器内要同时显示50+的按钮。使用vs控件开发的效果是按钮刷新较慢,肉眼观察有明显的延迟。一开始,想通过在容器内控制控件的重绘来加快刷新速度,未能实现。分析主要原因是,按钮重绘的延迟是因为系统逐个调用了每个按钮的重绘,而这一过程可能涉及到了按钮的其他一些操作,导致整体重绘速度降低。由于知识所限,目前在控件内无法提高刷新速度。经询问,决定使用自定义控件。思路是:在面板上自绘多按钮,并实现其点击响应。绘图部分应用System.Drawing.Graphics的支持,通过自定义事件的引发和响应实现对单个按钮的点击响应。
部分代码如下:
{
public partial class UserControl1 : UserControl //自定义控件类
{
#region Members
private int rowNo = 4; //Button的行数
private int colNo = 4;//Button的列数
private int bHeight = 30;//按钮的高
private int bWidth = 20;//按钮的宽
private int bBorder = 1;//按钮的边界宽度
private Size iSize =new Size(120,80);//控件大小
private String[][] title = null;//每个按钮的文本内容
private MyButton[][] _buttons = null;//自定义MyButton类的数组,用于引发事件
//记录鼠标按下的位置。行列,XY
private int lastR = 4;
private int lastC = 4;
private int lastX = 0;
private int lastY = 0;
//自定义事件成员
public event MyButtonEventHandle MyButtonEventHandle;
#endregion
#region Properties
[Description("The no. of rows"),Browsable(true),DisplayName("Row No."),Category("Settings of Button")]
public int RowNo
{
get { return rowNo; }
set {
if (value > 1)rowNo = value;
ButtonHeight = (this.Height-2) / rowNo;
}
}
[Description("The no. of columns"), Browsable(true), DisplayName("Col. No."), Category("Settings of Button")]
public int ColNo
{
get { return colNo; }
set {
if (value > 1)colNo = value;
ButtonWidth = (this.Width-2) / colNo;
}
}
[Description("height of button"), Browsable(true), DisplayName("ButtomHeight"), Category("Settings of Button")]
public int ButtonHeight
{
get { return bHeight; }
set {
if (value > 1)bHeight = value;
if (ButtonHeight * RowNo+2 != Size.Height)
{
this.Height = ButtonHeight * RowNo+2;
this.Size = new Size(this.Size.Width, ButtonHeight * RowNo+2);
}
}
}
[Description("Width of button"), Browsable(true), DisplayName("ButtomWidth"), Category("Settings of Button")]
public int ButtonWidth
{
get { return bWidth; }
set {
if (value > 1)bWidth = value;
if (ButtonWidth * ColNo+2 != Size.Width)
{
this.Width = ButtonWidth * ColNo+2;
this.Size = new Size(ButtonWidth * ColNo+2, this.Size.Height);
}
}
}
[Description("Width of button"), Browsable(true), DisplayName("ButtomBorder"), Category("Settings of Button")]
public int ButtonBorder
{
get { return bBorder; }
set { if (value > 0 && value < bWidth && value < bHeight)bBorder = value; }
}
public new Size Size
{
get {
iSize = base.Size;
return iSize;
}
set {
iSize = value;
base.Size = iSize;
if ((Size.Width-2) / ColNo != ButtonWidth || (Size.Height-2) / RowNo != ButtonHeight)
{
ButtonHeight = (Size.Height-2) / RowNo;
ButtonWidth = (Size.Width-2) / ColNo;
}
}
}
public string[][] Title
{
set { if(value.Length < (rowNo*colNo) || value.Length > 0)title = value; }
}
#endregion
public UserControl1()//构造函数
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)//控件OnLoad事件响应
{
base.OnLoad(e);
}
protected override void OnPaint(PaintEventArgs e)//绘制控件
{
base.OnPaint(e);
_buttons = new MyButton[rowNo][];
for (int i = 0; i < rowNo; i++)
{
_buttons[i] = new MyButton[colNo];
for (int j = 0; j < colNo; j++)
{
// Declare and instantiate a new pen.
Pen lightSide = new Pen(Color.White);
Pen darkSide = new Pen(Color.Black);
//设定初始按钮坐标
Point pos1 = new Point(j*ButtonWidth+1,i*ButtonHeight+1);
Point pos2 = new Point(j*ButtonWidth+1+ButtonWidth-ButtonBorder,i*ButtonHeight+1);
Point pos3 = new Point(j * ButtonWidth + 1, i * ButtonHeight + 1 + ButtonHeight - ButtonBorder);
Point pos4 = new Point(j * ButtonWidth + 1 + ButtonWidth - ButtonBorder, i * ButtonHeight + 1 + ButtonHeight - ButtonBorder);
Size size = new Size(ButtonWidth - ButtonBorder, ButtonHeight-ButtonBorder);
//绘制按钮
e.Graphics.DrawLine(lightSide, pos1, pos2);
e.Graphics.DrawLine(lightSide, pos1, pos3);
e.Graphics.DrawLine(darkSide, pos2, pos4);
e.Graphics.DrawLine(darkSide, pos3, pos4);
//绘制按钮文本
if (title == null)
{
e.Graphics.DrawString(i + "," + j, new Font(FontFamily.GenericSerif, 9.0f), Brushes.Blue, pos1);
_buttons[i][j] = new MyButton(i, j, i + "," + j);
}
else {
e.Graphics.DrawString(title[i][j].ToString(), new Font(FontFamily.GenericSerif, 9.0f), Brushes.Blue, pos1);
_buttons[i][j] = new MyButton(i, j, title[i][j].ToString());
}
}
}
}
private void Do_Down(Object sender, MouseEventArgs e)//响应鼠标按下事件
{
int x,y,inx,iny;
x = e.X;
y = e.Y;
inx = x % (bWidth-bBorder);
iny = y % (bHeight-bBorder);
lastX = x / bWidth;
lastY = y / bHeight;
if (inx < bWidth && iny < bHeight && lastX < colNo && lastY < rowNo)
{
System.Drawing.Pen myPen = new System.Drawing.Pen(Color.Black);
Point pos1 = new Point(lastX * bWidth + 1, lastY * bHeight + 1);
Point pos2 = new Point(lastX * bWidth + 3, lastY * bHeight + 3);
Point pos3 = new Point(lastX * ButtonWidth + 1 + ButtonWidth - ButtonBorder, lastY * ButtonHeight + 1);
Point pos4 = new Point(lastX * ButtonWidth + 1, lastY * ButtonHeight + 1 + ButtonHeight - ButtonBorder);
Size size = new Size(bWidth - bBorder + 2, bHeight - bBorder + 2);
Graphics a = this.CreateGraphics();
a.DrawLine(myPen, pos1, pos3);
a.DrawLine(myPen, pos1, pos4);
for (int pointX = (lastX * bWidth + 6); pointX < (lastX * bWidth + 1 + ButtonWidth - ButtonBorder - 2); pointX += 2)
{
a.DrawLine(myPen, pointX, lastY * bHeight + 2, pointX + 1, lastY * bHeight + 3);
a.DrawLine(myPen, pointX, lastY * bHeight + bHeight - 3 - ButtonBorder, pointX + 1, lastY * bHeight + bHeight -1 - ButtonBorder);
}
for (int pointY = (lastY * bHeight + 6); pointY < (lastY * bHeight + 1 + ButtonHeight - ButtonBorder - 2); pointY += 2)
{
a.DrawLine(myPen, lastX * bWidth + 2, pointY, lastX * bWidth + 3, pointY+1);
a.DrawLine(myPen, lastX * bWidth -2 - ButtonBorder + bWidth, pointY, lastX * bWidth - ButtonBorder + bWidth-1, pointY + 1);
}
if (title == null)
{
a.DrawString(lastY + "," + lastX, new Font(FontFamily.GenericSerif, 9.0f), new SolidBrush(this.BackColor), pos1);
a.DrawString(lastY + "," + lastX, new Font(FontFamily.GenericSerif, 9.0f), Brushes.Blue, pos2);
}
else
{
a.DrawString(title[lastY][lastX].ToString(), new Font(FontFamily.GenericSerif, 9.0f), new SolidBrush(this.BackColor), pos1);
a.DrawString(title[lastY][lastX].ToString(), new Font(FontFamily.GenericSerif, 9.0f), Brushes.Blue, pos2);
}
lastC = lastX;
lastR = lastY;
}
else { }
}
private void Do_Up(Object sender, MouseEventArgs e)//响应鼠标松开事件
{
if (lastR < rowNo && lastC < colNo)
{
System.Drawing.Pen myPen = new System.Drawing.Pen(this.BackColor);
Pen lightSide = new Pen(Color.White);
Point pos1 = new Point(lastX * bWidth + 1, lastY * bHeight + 1);
Point pos2 = new Point(lastX * bWidth + 3, lastY * bHeight + 3);
Point pos3 = new Point(lastX * ButtonWidth + 1 + ButtonWidth - ButtonBorder, lastY * ButtonHeight + 1);
Point pos4 = new Point(lastX * ButtonWidth + 1, lastY * ButtonHeight + 1 + ButtonHeight - ButtonBorder);
Size size = new Size(bWidth - bBorder + 2, bHeight - bBorder + 2);
Graphics a = this.CreateGraphics();
string _buttonText = null;
a.DrawLine(lightSide, pos1, pos3);
a.DrawLine(lightSide, pos1, pos4);
for (int pointX = (lastX * bWidth + 6); pointX < (lastX * bWidth + 1 + ButtonWidth - ButtonBorder - 2); pointX += 2)
{
a.DrawLine(myPen, pointX, lastY * bHeight + 2, pointX + 1, lastY * bHeight + 3);
a.DrawLine(myPen, pointX, lastY * bHeight + bHeight - 3 - ButtonBorder, pointX + 1, lastY * bHeight + bHeight - 1 - ButtonBorder);
}
for (int pointY = (lastY * bHeight + 6); pointY < (lastY * bHeight + 1 + ButtonHeight - ButtonBorder - 2); pointY += 2)
{
a.DrawLine(myPen, lastX * bWidth + 2, pointY, lastX * bWidth + 3, pointY + 1);
a.DrawLine(myPen, lastX * bWidth - 2 - ButtonBorder + bWidth, pointY, lastX * bWidth - ButtonBorder + bWidth - 1, pointY + 1);
}
if (title == null)
{
a.DrawString(lastY + "," + lastX, new Font(FontFamily.GenericSerif, 9.0f), new SolidBrush(this.BackColor), pos2);
a.DrawString(lastY + "," + lastX, new Font(FontFamily.GenericSerif, 9.0f), Brushes.Blue, pos1);
_buttonText = lastR.ToString()+","+lastC.ToString();
}
else
{
a.DrawString(title[lastY][lastX].ToString(), new Font(FontFamily.GenericSerif, 9.0f), new SolidBrush(this.BackColor), pos2);
a.DrawString(title[lastY][lastX].ToString(), new Font(FontFamily.GenericSerif, 9.0f), Brushes.Blue, pos1);
_buttonText = title[lastY][lastX];
}
//引发自定义事件
MyButtonClickEventArgs _newEvent = new MyButtonClickEventArgs(_buttons[lastR][lastC]);
OnClick(_newEvent);
}
else { }
}
public Point GetButtonIndex()
{
Point index = new Point(lastR, lastC);
return index;
}
protected virtual void OnClick(MyButtonClickEventArgs e)
{
//调用委托的函数相应事件
if (MyButtonEventHandle != null)
MyButtonEventHandle(this, e);
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
PaintEventArgs pe = new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle);
this.RaisePaintEvent(this, pe);
}
}
//定义自定义事件的EventHandle。相当于声明了方法变量。
public delegate void MyButtonEventHandle(object sender, MyButtonClickEventArgs args);
//自定义按钮事件
public class MyButtonClickEventArgs : EventArgs
{
private readonly MyButton _button;
public MyButtonClickEventArgs(MyButton button)
{
_button = button;
}
public MyButton OnClickButton
{
get { return _button; }
}
}
//自定义类MyButton,作为自定义事件的属性类型。
public class MyButton
{
private readonly int _row = -1;
private readonly int _col = -1;
private readonly string _buttontext = null;
public MyButton(int row, int col, string text)
{
_buttontext = text;
_row = row;
_col = col;
}
public int Row
{
get { return _row; }
}
public int Col
{
get { return _col; }
}
public string ButtonText
{
get { return _buttontext; }
}
}
}
- vs 自绘控件--自绘多按钮控件
- 【自绘控件之按钮类】
- Button按钮控件自绘操作
- 自绘按钮控件属性自绘属性的保持
- 控件自绘
- 自绘控件笔记
- 自绘 列表控件
- 自绘 tab 控件
- 自绘CStatic控件
- 自绘GridView控件
- 自绘控件笔记
- EDIT控件自绘
- 控件自绘
- 控件自绘Static
- MFC 自绘控件
- VC控件自绘
- CStatic控件自绘
- View自绘控件
- 引自 小狼ing 的几句话,很感伤,很道理,很亲切
- J2ME开发
- 《编程之美》背后的作者之美
- Javascript版的下拉框联动
- JNDI设计内幕
- vs 自绘控件--自绘多按钮控件
- Windows 下 快捷键列表
- 对MDB文件的操作
- 程序员的成长由此开始
- asp.net MD5加密函数
- 新概念英语第三册第一课
- Blended Learning Media Type
- [Behavioral Patterns #1] Chain of responsibilty
- 上传文件到数据库,然后下载文件