winform控件开发总结
winform控件开发总结。
1.开发控件tabcontrol.继承自system.windows.controls下面的tabcontrol。重写事件OnPaint
在里面重绘了tab区域。
private void DrawControl(Graphics graphics) { //外层矩形 Rectangle tabControlArea = this.ClientRectangle; //Fill client area //Brush brush = new SolidBrush(SystemColors.Control); Brush brush = new SolidBrush(Color.White); graphics.FillRectangle(brush, tabControlArea); //graphics.DrawRectangle(new Pen(Color.DarkRed), tabControlArea); brush.Dispose(); //内层矩形 Rectangle tabArea = this.DisplayRectangle; ////border //int nDelta = SystemInformation.BorderSize.Width; ////Pen border = new Pen(SystemColors.Highlight); //Pen border = new Pen(Color.White); //tabArea.Inflate(nDelta, nDelta); //graphics.DrawRectangle(border, tabArea); //clip region for drawing tabs Region rSaved = graphics.Clip; Rectangle rRec = new Rectangle(tabArea.Left, tabControlArea.Top, tabArea.Width, tabControlArea.Height); graphics.SetClip(rRec); for (int i = 0; i < this.TabCount; i++) { DrawTab(graphics, this.TabPages[i], i); } graphics.Clip = rSaved; } internal void DrawTab(Graphics g, TabPage tabPage, int nIndex) { Rectangle recBounds = this.GetTabRect(nIndex); Rectangle tabMy=new Rectangle(recBounds.X,recBounds.Y,this.Width,recBounds.Height); var backSb = new SolidBrush(Color.FromArgb(233,242,246)); g.FillRectangle(backSb, tabMy); RectangleF tabTextArea = (RectangleF)this.GetTabRect(nIndex); bool bSelected = (this.SelectedIndex == nIndex); Point[] pt = new Point[7]; if (this.Alignment == TabAlignment.Top) { pt[0] = new Point(recBounds.Left, recBounds.Bottom); pt[1] = new Point(recBounds.Left, recBounds.Top + 3); pt[2] = new Point(recBounds.Left + 3, recBounds.Top); pt[3] = new Point(recBounds.Right - 3, recBounds.Top); pt[4] = new Point(recBounds.Right, recBounds.Top + 3); pt[5] = new Point(recBounds.Right, recBounds.Bottom); pt[6] = new Point(recBounds.Left, recBounds.Bottom); } else { pt[0] = new Point(recBounds.Left, recBounds.Top); pt[1] = new Point(recBounds.Right, recBounds.Top); pt[2] = new Point(recBounds.Right, recBounds.Bottom - 3); pt[3] = new Point(recBounds.Right - 3, recBounds.Bottom); pt[4] = new Point(recBounds.Left + 3, recBounds.Bottom); pt[5] = new Point(recBounds.Left, recBounds.Bottom - 3); pt[6] = new Point(recBounds.Left, recBounds.Top); } //---------------------------- // fill this tab with background color Brush br = new SolidBrush(Color.Yellow); var pageImageNormal = Image.FromFile(@"Resources\rtab_normal.png"); g.DrawImage(pageImageNormal, recBounds); //g.FillPolygon(br, pt); br.Dispose(); //---------------------------- //---------------------------- // draw border //g.DrawRectangle(SystemPens.ControlDark, recBounds); //g.DrawPolygon(SystemPens.ControlDark, pt); //var pen3 = new Pen(tabBackColor, 1); var pen3 = new Pen(Color.White, 1); g.DrawPolygon(pen3,pt); pen3.Dispose(); if (bSelected) { //---------------------------- // clear bottom lines Pen pen = new Pen(tabPage.BackColor); switch (this.Alignment) { case TabAlignment.Top: g.DrawLine(pen, recBounds.Left + 1, recBounds.Bottom, recBounds.Right - 1, recBounds.Bottom); g.DrawLine(pen, recBounds.Left + 1, recBounds.Bottom + 1, recBounds.Right - 1, recBounds.Bottom + 1); break; case TabAlignment.Bottom: g.DrawLine(pen, recBounds.Left + 1, recBounds.Top, recBounds.Right - 1, recBounds.Top); g.DrawLine(pen, recBounds.Left + 1, recBounds.Top - 1, recBounds.Right - 1, recBounds.Top - 1); g.DrawLine(pen, recBounds.Left + 1, recBounds.Top - 2, recBounds.Right - 1, recBounds.Top - 2); break; } pen.Dispose(); //---------------------------- } //---------------------------- ////---------------------------- //// draw string StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.LineAlignment = StringAlignment.Center; br = new SolidBrush(tabPage.ForeColor); g.DrawString(tabPage.Text, Font, br, tabTextArea, stringFormat); //---------------------------- }
这个不存在问题。因为一般的时候重绘这个控件都会重写这个部门。添加些自己的见面要求。
但是都不会重绘tabpage。这个就是整个区域中四方形的部分。
如果不重写这个部分。在放置控件的时候就会有些问题。出现一个灰色条形线。
这是因为控件在嵌入的时候不是占用这个控件区域,它会留下一块边区域。
因此,tabpage对象的背景色要和主Penel的背景色一致。
2.TreeView控件的DrawNode事件
void MyTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e) { //e.Graphics.SetClip(NodeBounds(e.Node)); if ((e.State & TreeNodeStates.Selected) != 0) { Color myColor = Color.FromArgb(135, 223, 250); SolidBrush sb = new SolidBrush(myColor); e.Graphics.FillRectangle(sb, NodeBounds(e.Node)); sb.Dispose(); TreeViewDrawString(sender, e.Node,Brushes.Red); } else { //e.DrawDefault = true; TreeViewDrawString(sender, e.Node, Brushes.Black); }
它在点击打开子节点的时候,不会重绘最上边节点。会造成上面部分字体重合显示。该问题一直没找到是什么原因造成的。