Idle talk ~
I. Custom tab button
The left part of the tab button is text, and the right part is the close button;
This button has two statuses: select and not selected
If the button is not selected, the background color changes to light blue when you move the mouse over it;
The selected button background color is yellow
Close the button and move the mouse up to a dark yellow color.
Properties involved in the control and public event Properties
/// <Summary> /// tab title /// </Summary> Public String Caption; /// <summary> /// select or not /// </Summary> bool isselected = true; /// <summary> // text color /// </Summary> color strcolor = color. black; // <summary> /// width /// </Summary> int strwidth; /// <summary> /// selected event /// </Summary> [browsable (true)] [editorbrowsable (editorbrowsablestate. always)] public event eventhandler onselect; // <summary> // click the close button event /// </Summary> [browsable (true)] [editorbrowsable (editorbrowsablestate. always)] public event eventhandler onclose;
The annotations are clear.
Next, let's look at the events of this control.
/// <Summary> /// move the cursor to the event // </Summary> /// <Param name = "sender"> </param> /// <Param name = "E"> </param> private void tabbtn_mouseenter (Object sender, eventargs e) {If (! Isselected) {This. backcolor = colortranslator. fromhtml ("#4d6082 ");}} /// <summary> /// mouse removal event /// </Summary> /// <Param name = "sender"> </param> /// <Param name = "E"> </param> private void tabbtn_mouseleave (Object sender, eventargs e) {If (! Isselected) {This. backcolor = colortranslator. fromhtml ("#293955 ");}} /// <summary> /// move the mouse event /// </Summary> /// <Param name = "sender"> </param> /// <Param name = "E"> </param> private void tabbtn_mousemove (Object sender, mouseeventargs e) {var flag = ismouseonclosepoint (); If (FLAG) {drawcontrol (color. black, color. fromargb (INT) (byte) (255), (INT) (byte) (232), (INT) (byte) (166);} else {drawcontrol (strcolor, this. backcolor );}} /// <summary> /// redraw event /// </Summary> /// <Param name = "sender"> </param> /// <Param name = "E"> </param> private void tabbtn_paint (Object sender, painteventargs e) {drawcontrol (strcolor, this. backcolor );}
Both the move event and the move event are triggered.
To move an event, you must first determine the location of the mouse;
Then draw controls in different colors based on the mouse position
The following describes how to draw controls and determine the mouse position.
/// <Summary> /// rewrite creation event /// </Summary> protected override void oncreatecontrol () {base. oncreatecontrol (); var G = This. creategraphics (); strwidth = (INT) g. measurestring (Caption, systemfonts. defaultfont ). width; G. dispose (); this. width = strwidth + 24 ;} /// <summary> /// draw control /// </Summary> /// <Param name = "fore"> </param> /// <Param name = "BG"> </param> void drawcontrol (color fore, color BG) {var G = This. creategraphics (); G. drawstring (Caption, systemfonts. defaultfont, new solidbrush (strcolor), new pointf (3, 8); var P = new pen (fore, (float) 1); G. fillrectangle (New solidbrush (BG), new rectangle (strwidth + 6, 7, 13, 13); G. translatetransform (strwidth + 12, 13); G. rotatetransform (45); For (VAR I = 0; I <4; I ++) {G. rotatetransform (90); G. drawline (p, 0, 0, 6, 0);} G. resettransform (); p. dispose (); G. dispose () ;}/// <summary> /// mouse position /// </Summary> /// <returns> </returns> Public bool ismouseonclosepoint () {var P = This. pointtoclient (mouseposition); var CRX = new rectangle (strwidth + 3, 3, 16, 16); Return CRX. contains (p );}
We obtained the text width when creating the control.
Draw the widget text and close button positions based on the width.
We defined the event handler for this control in the property.
Next let's take a look at how these Handler are triggered.
/// <Summary> /// uncheck /// </Summary> Public void disselectme () {isselected = false; this. backcolor = colortranslator. fromhtml ("#293955"); strcolor = color. white; drawcontrol (strcolor, this. backcolor) ;}/// <summary> /// select /// </Summary> Public void selectme () {isselected = true; this. backcolor = systemcolors. info; strcolor = color. black; drawcontrol (strcolor, this. backcolor );} /// <summary> /// trigger the Custom Event /// </Summary> /// <Param name = "sender"> </param> // <Param name = "E"> </param> private void tabbtn_click (Object sender, eventargs e) {var flag = ismouseonclosepoint (); If (FLAG) {onclose (this, eventargs. empty);} else {If (isselected) {return;} onselect (this, eventargs. empty); selectme ();}}
So far, the creation of the tab button has been completed.
It may not be perfect in some places ~ Comments and corrections
Ii. Basic Types of business forms
All business forms inherit from this base class baseform
This form base class has three public attributes
/// <Summary> /// menu data /// </Summary> Public menumodel formmenu {Get; set ;} /// <summary> // tab button // </Summary> Public tabbtn formtabbtn {Get; set ;} /// <summary> /// sub-menu /// </Summary> Public label submenu {Get; set ;}
These three attributes will be used later
I will not talk about it here
/// <Summary> /// constructor /// </Summary> Public baseform () {initializecomponent (); this. toplevel = false ;}
Generally, top-level forms cannot be placed as sub-controls in container controls.
Therefore, we need to set the toplevel attribute of the form.
/// <Summary> /// click the tab button to select an event; /// </Summary> /// <Param name = "sender"> </param> /// <Param name = "E"> </param> Public Virtual void tbn_onselect (Object sender, eventargs e) {This. show ();} /// <summary> /// tab button to close the event /// </Summary> /// <Param name = "sender"> </param> // <Param name = "E"> </param> Public Virtual void tbn_onclose (Object sender, eventargs e) {This. close ();}
These are two events of the tab button ~
Registered when the tab button is created ~
How can we create the tab button and register these two events later ~
Because it is not a tab button created in baseform
Private void baseform_visiblechanged (Object sender, eventargs e) {If (utils. isindesignmode () {return;} This. visiblechanged-= new eventhandler (baseform_visiblechanged); var mf = utils. getmainform (); If (this. visible) {foreach (var hf in MF. formhistory) {If (HF. formmenu. URL. equals (this. formmenu. URL) {continue;} If (HF. visible) {HF. hide () ;}} formtabbtn. selectme (); Mf. formhistory. remove (this); Mf. formhistory. insert (0, this); Mf. maincontainerp. controls. clear (); Mf. maincontainerp. controls. add (this); submenu. backcolor = systemcolors. info; // todo: The system name can be used to remove MF from the database. TEXT = string. format ("XXX management system-{0}", formmenu. menuname);} else {formtabbtn. disselectme (); submenu. backcolor = color. transparent;} This. visiblechanged + = new eventhandler (baseform_visiblechanged );}
This is an important event of baseform.
Triggered when switching between hide and display
If it changes from hide to show
First, traverse all opened business forms. If any of them is in the display status, hide them, because the current system can only have one business form in the display status.
Then select the tab button,
The remove and insert operations of formhistory are mainly used to enable the system to remember which forms have been recently displayed;
Maincontainerp's clear and add are used to display the form in the container control.
If you change from show to hide
The tab button is deselected,
The background color of the sub-menu is transparent (in fact, the sub-menu is deselected)
Event registration canceled at the beginning of Event Processing
At the end of event processing, the event is registered.
To avoid multiple triggering events
Utils. getmainform (); obtainCodeAs follows:
/// <Summary> /// Main Window /// </Summary> Private Static mainform MF; /// <summary> /// obtain the main window /// </Summary> /// <returns> </returns> Public static mainform getmainform () {If (mf = NULL) {mf = application. openforms ["mainform"] As mainform;} return MF ;}
Some logic should be processed when the business form is closed
The Code is as follows:
Private void baseform_formclosing (Object sender, formclosingeventargs e) {This. visiblechanged-= new eventhandler (baseform_visiblechanged); var mf = utils. getmainform (); Mf. formhistory. remove (this); this. submenu. backcolor = color. transparent; If (MF. formhistory. count> 0) {MF. formhistory [0]. show ();} foreach (var f in MF. formhistory) {If (F. formtabbtn. left> formtabbtn. left) {f. formtabbtn. left-= (formtabbtn. width + 6) ;}} MF. tabcontainerp. controls. remove (formtabbtn );}
Cancel event registration
Remove history
Deselect a sub-menu
Open the last opened business form (if any)
Override the position of the tab button (mainly the tab button on the right of the closed tab button)
Delete Tab
3. dynamically create a business form
In the previous section, We only talked about the slide-in and out events of sub-menus, but not the click events.
Click an event to create a business form event.
Let's take a look at the code.
/// <Summary> /// the sub-menu pops up the event // </Summary> /// <Param name = "sender"> </param> // <Param name = "E"> </param> void sm_mouseup (Object sender, mouseeventargs e) {var lB = sender as label; var M = LB. tag as menumodel; If (string. isnullorempty (M. URL) {utils. alert ("no business form related to this menu"); return;} baseform F = NULL; foreach (var hf in formhistory) {If (HF. formmenu. URL. equals (M. URL) {f = Hf; break;} If (F = Null) {f = createoneform (m); F. submenu = LB;} If (F! = NULL &&! F. Visible) {f. Show ();}}
In fact, there are not many business logic in this method.
F = createoneform (m);
/// <Summary> /// create a business form; including the tab button /// </Summary> /// <Param name = "M"> </param> private baseform createoneform (menumodel m) {var ass = This. getType (). assembly; var url = string. format ("XL. client. forms. {0} ", M. URL); baseform F = NULL; try {f = ass. createinstance (URL) as baseform;} catch {utils. alert ("no business form related to this menu"); return NULL;} f. dock = dockstyle. fill; F. formmenu = m; var tabbtn = new tabbtn (); tabbtn. onclose + = new eventhandler (F. tbn_onclose); tabbtn. onselect + = new eventhandler (F. tbn_onselect); tabbtn. caption = m. menuname; int left = 6; var tabcount = tabcontainerp. controls. count; If (tabcount> 0) {var lasttab = tabcontainerp. controls [tabcount-1]; left + = (lasttab. left + lasttab. width);} tabbtn. left = left; tabcontainerp. controls. add (tabbtn); F. formtabbtn = tabbtn; return F ;}
We took out the URL field of the menu and reflected an instance of a business form.
Then, create an instance with the tab button and let the business form hold the instance.
Note how to register the close and select events of the tab button ~ Kiss ~
Okay ~ That's all ~
There are many contents today ~
Write in a hurry ~ If you have any questions, please feel free to mention them ~
The following content: logon, pop-up screen, client cache data, and WCF security verification
Uncle ~ Dayu ~ Eldest Brother ~ Sister-in-law ~ Sister-in-law ~ Click here for recommendation ~ Click here for recommendation ~