When rewriting tabcontrol, we first thought of setting
This. drawmode = tabdrawmode. ownerdrawfixed;
Then rewrite
protected override void OnDrawItem(DrawItemEventArgs e){ base.OnDrawItem(e);}
In this way, only the area on the tab is overwritten. This area does not include borders. In this way, the rewritten area and the border are not tuned and cannot achieve the functions we want.
The better way is to overwrite the entire control.
Set controls to be drawn by users
private void SetStyles() { base.SetStyle( ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); base.UpdateStyles(); }
The key is to set controlstyles. userpaint to true.
Override onpaint
Protected override void onpaint (painteventargs PE) {base. onpaint (PE); PE. graphics. smoothingmode = smoothingmode. antialias; PE. graphics. interpolationmode = interpolationmode. highqualitybilinear; // PE. graphics. textrenderinghint = textrenderinghint. antialias; // draw the background rectangle rect = This. clientrectangle; PE. graphics. fillrectangle (New texturebrush (properties. resources. BG), rect); // draw the edge int Height = This. itemsize. height + 3; rectangle r = new rectangle (displayrectangle. x-1, displayrectangle. y-1, displayrectangle. width + 1, displayrectangle. height + 1); // PE. graphics. drawline (new pen (color. fromargb (157,162,168), new point (rect. x, rect. Y + height), new point (rect. right, rect. Y + height); PE. graphics. drawrectangle (new pen (_ linecolor), R); // draw a border // draw a header foreach (tabpage TP in this. tabpages) {drawtabpage (PE. graphics, this. gettabrect (this. tabpages. indexof (TP), TP );}}
This. The location of the tag that can be obtained by the gettabrect function, which helps us to re-paint the tag.
Redraw tags
Private void drawtabpage (Graphics graphics, rectangle, tabpage TP) {// draw the baseline stringformat Sf = new stringformat (); SF. trimming = stringtrimming. ellipsischaracter; SF. formatflags = stringformatflags. nowrap; rectangle rect = new rectangle (rectangle. x, rectangle. Y + 2, rectangle. width, rectangle. height-2); // standard region rectangle fontrect = new rectangle (rectangle. X + 5, rectangle. Y + 5, rectangle. width-10, TP. font. height); // text area if (this. selectedtab. equals (TP) {rect = new rectangle (rectangle. x, rectangle. y, rectangle. width, rectangle. height); fontrect = new rectangle (rectangle. X + 5, rectangle. Y + 5, rectangle. width-25, rectangle. height-7); // draw the border graphics. fillpath (New lineargradientbrush (new point (rect. x, rect. y), new point (rect. x, rect. Y + rect. height), _ col1_tivatea, _ col1_tivateb), createtabpath (rect); // fill the color graphics. drawstring (TP. text, TP. font, new solidbrush (TP. forecolor), fontrect, SF); // graphics for text plotting. drawpath (new pen (_ linecolor), createtabpath (rect); // draw real edges // mask the lower part of graphics. drawline (new pen (_ col1_tivateb, 3), rect. x, rect. bottom + 1, rect. X + rect. width, rect. bottom + 1); // draw the image rectangle rectclose = getcloserect (rectangle);} else {// draw the border graphics. fillpath (New lineargradientbrush (new point (rect. x, rect. y), new point (rect. x, rect. Y + rect. height), _ colordefaulta, _ colordefaultb), createtabpath (rect); // fill the color graphics. drawstring (TP. text, TP. font, new solidbrush (TP. forecolor), fontrect, SF); // text drawing // graphics. drawpath (new pen (color. wheat, 2), createtabpath (rect); // draw the high-gloss edge graphics. drawpath (new pen (_ linecolor), createtabpath (rect); // draw real edges}
Close tag button
We added a function for the label to move the mouse up and show the close button to rewrite the onmousemove function.
bool CloseEX = false; protected override void OnMouseMove(MouseEventArgs e) { if (TabPageMouseClose(e.Location) != CloseEX) { CloseEX = !CloseEX; this.Invalidate(); } base.OnMouseMove(e); }
When the mouse moves too fast, it will cause the close button to be not refreshed, and we will make closeex = false and redraw again when the mouse leaves the control.
In this step, we will complete our drawing. I used a gradient Paint Brush during painting and used five parameters to identify each specified color.
Private color _ linecolor = color. fromargb (157,162,168); // edge color private color _ colordefaulta = color. fromargb (231,231,231); // default label gradient vate color _ colordefaultb = color. fromargb (255,255,255); // default label gradient bprivate color _ col1_tivatea = color. fromargb (184,203,217); // click the Gradient Variable vate color _ col1_tivateb = color. fromargb (255,255,255); // click gradient