UI(User InterfaceProgramming is an important part in the entire project development process. If any good solution is not presented to the end user with a good user interface, even if it includes the most advanced technology
Not goodProgram.UIProgramming is embodied in two aspects. One is the exquisite user interface, and the other is an easy-to-use operation flow that conforms to most user habits, and creates a beautiful and colorful user world.
Face is the first step to win the favor of end users. Let's use the 3D button in a crystal style as an example to enrich. NetInterface Material library, which isWindowsAdd highlights to the form program.
I. Key Technical Points
It is undeniable that, Windows Programming has entered . Net In the era, although many programming platforms exist . Net The framework class library has fully occupied the mainstream position. . Net The Framework provides us with a wealth of classes, functions, and methods, from desktop Web It can touch any field of programming, so that it can give up completely Win32 API Because . Net The Framework has prepared everything for us. Especially GDI + , Win32 Programmers should be very clear about Vc6 And Delphi5 , 6 , 7 To
It is not easy to draw a window control with irregular graphics and a unique style. We need to return the current device pointer, map coordinates, and then call the standard Win32
GDI Function to draw, and finally remember to release the device pointer and a series of memory cleanup operations, now . Net Class Library, we only need Onpaint Event passedE. Graphics Return Graphics And then create a custom brush object. Brush To fill Graphics And create another Region Objects to design the desired control outlines and assign them to Region Attribute, which can be used in this process GDI + We provide a wide range of classes and methods to design the elegant widget exterior.
The new control is created.
Our example control is a crystal-style three-dimensional button. designing such a button control is not complicated. We only need to captureOnpaintEvent, and in the event according to different button status, such as: move the mouse into, hover the mouse, click the mouse, and move the mouse away and re-draw the appearance of the button. The three-dimensional style of the button is actually the stacked of three rectangular areas.
Add, that is, the shadow is located at the bottom layer, the button itself, and the white bubble part of the top-layer button header. These three parts are effectively superimposed and made into a vivid crystal style button, as shown in:
The key class used in this example isGraphicspath,LineargradientbrushAndPathgradientbrush. We already know that complex graphic drawing operations will be usedGraphicspathObject,GraphicspathIt provides us with a very convenient solution, which consists of a series of straight lines and curved lines. By creating complex closed paths, we can easily create any irregular graphics;LineargradientbrushAndPathgradientbrushThe object is
We have successfully created the key classes of the sample program. They all inherit from the base class.Brush,BrushObject defines the objects used to fill the shape of the image.LineargradientbrushCreate an instance of this Class Based on the starting and ending coordinates and the starting and ending colors of the gradient. This class supports two-color gradient and custom multi-color gradient, all gradient
They are all defined along the width of the rectangle or a straight line specified by two points. By default, a two-color gradient is an even horizontal linear mixture from the starting color to the ending color along the specified line. Therefore, based on this feature, we use this class to draw the white gradient section on the button itself and the top of the button.CodeAs follows:
//Create a graph of the button itself
Rectangle rc = new rectangle (btnoffset, btnoffset, this. clientsize. Width-8-
Btnoffset, this. clientsize. Height-8-btnoffset );
Graphicspath path1 = This. getgraphicspath (RC, 20 );
Lineargradientbrush br1 = new lineargradientbrush (new point (0, 0), new point (0,
RC. height + 6), color. Blue, color. White );
//Create a white gradient at the top of the button
Rectangle RC3 = RC;
Rc3.inflate (-5,-5 );//
Rc3.height = 15;
Graphicspath path3 = getgraphicspath (RC3, 20 );
Lineargradientbrush Br3 = new lineargradientbrush (RC3, color. fromargb (255,
Color. White), color. fromargb (0, color. White), lineargradientmode. Vertical)
PathgradientbrushClass filling by GradientGraphicspathInside the object, it can perform a smooth color gradient from the midpoint of the path to the edge of the outer border of the path. We use this class to create the shadow part of the button,CentercolorAttribute is used to set the color at the center of the path gradient, that is, black,SurroundcolorsArray is used to set the color array corresponding to the midpoint of the path. Some code is as follows:
Below:
Rectangle RC2 = RC;
Rc2.offset (shadowoffset, shadowoffset );
Graphicspath path2 = This. getgraphicspath (RC2, 20 );
Pathgradientbrush Br2 = new pathgradientbrush (path2 );
Br2.centercolor = color. Black;
Br2.surroundcolors = new color [] {systemcolors. buttonface };
//To be more realistic, we set the gradient end color to the foreground color of the form, which can be adjusted according to the foreground color of the window.
After the instance of this object is created, the shadow image is filled with a radial gradient. The reader may ask why the shadow image must be used.PathgradientbrushFill in the image, instead of using
LineargradientbrushWhat about it? In fact, the reason is very simple. It is to ensure that the color and degree of the Shadow gradient at the bottom and right of the button are consistent. Otherwise, if linear gradient is usedLineargradientbrushThe result is as follows:
ThreeBrushObject instanceBr1,Br2AndBr3After the creation, we need to follow the order of shadow, button itself, and finally the white gradient at the top of the button.
Draw them. CallGraphicsObjectFillpathThree different methods are used:BrushObject To FillGraphicspathIn this way, 3D buttons with crystal styles are basically created. Finally, we reuse. NetThe second-level cache plotting technology draws the button and the text displayed on the button to the screen.
II. Implementation
We useC #To create a crystal button control.
StartVisual Studio 2005To create a blank solution:TestcrystalbuttonIn the project navigation bar, right-click to add a new project.C # windowsControl library, namedMycontrols.IDECreatesUsercontrolNameUsercontrol1Class, modify the code to inherit fromButtonAnd all references in the original fileUsercontrol1The name is changedCrystalbuttonIn the project navigation barUsercontrol1.csRenamedCrystalbutton. CS, As shown in the following code:
Namespace mycontrols
{
Public partial class crystalbutton:
Button
{
Public crystalbutton ()
{
Initializecomponent ();
}
}
}
ThenInitializecomponent ()Method
This. autoscalemode = system. Windows. Forms. autoscalemode. Font;
Comment out the sentence becauseButtonThe widget cannot be scaled automatically. It must depend on its parent widget. Add a pair in the source File HeaderSystem. Drawing. ImagingAnd
System. Drawing. drawing2dAssembly reference. First, you must create an enumeration type.MouseactiontypeWhen the button needs to be drawn
Draw different States with the cursor position, as shown in the following code:
......
Private Enum mouseactiontype
{
None,
Hover,
Click
}
Private mouseactiontype mouseaction;
Control will captureOnmousedown,Onmouseup,Onmousehover,OnmouseenterAndOnmouseleaveEvent andMouseactionThe variable is set to different enumerated values so thatOnpaintWhen an event occursMouseactionVariables are drawn in different States.
ControlOnpaintAn event is the most important code segment in the project. It is drawn based on the three parts of the button, and the text of the button is also drawn to the button surface, the second-level cache plotting technology is used for all operations. The Code is as follows:
Protected override void onpaint (painteventargs E)
{
Graphics G = E. graphics;
G. Clear (systemcolors. buttonface );
Color CLR = This. backcolor;
Int shadowoffset = 8;
Int btnoffset = 0;
Switch (mouseaction)
{
Case mouseactiontype. CLICK:
Shadowoffset = 4;
CLR = color. lightgray;
Btnoffset = 2;
Break;
Case mouseactiontype. Hover:
CLR = color. lightgray;
Break;
}
G. smoothingmode = smoothingmode. antialias;
// Create a graph of the button itself
Rectangle rc = new rectangle (btnoffset, btnoffset,
This. clientsize. Width-8-btnoffset, this. clientsize. Height-8-btnoffset );
Graphicspath path1 = This. getgraphicspath (RC, 20 );
Lineargradientbrush br1 = new lineargradientbrush (New
Point (0, 0), new point (0, RC. height + 6), CLR, color. White );
// Create button shadow
Rectangle RC2 = RC;
Rc2.offset (shadowoffset, shadowoffset );
Graphicspath path2 = This. getgraphicspath (RC2, 20 );
Pathgradientbrush Br2 = new pathgradientbrush (path2 );
Br2.centercolor = color. Black;
Br2.surroundcolors = new color []
{Systemcolors. buttonface };
// To be more realistic, we set the gradient end color to the foreground color of the form, which can be adjusted according to the foreground color of the window.
// Create a white gradient at the top of the button
Rectangle RC3 = RC;
Rc3.inflate (-5,-5 );
Rc3.height = 15;
Graphicspath path3 = getgraphicspath (RC3, 20 );
Lineargradientbrush Br3 = new lineargradientbrush (RC3,
Color. fromargb (255, color. White), color. fromargb (0, color. White ),
Lineargradientmode. Vertical );
// Drawing
G. fillpath (Br2, path2 );// Draw shadow
G. fillpath (br1, path1 );// Draw button
G. fillpath (Br3, path3 );// Draw top White bubbles
// Sets the memory bitmap object and performs second-level cache plotting.
Buttonbitmaprectangle =
Note: no source of the original text can be found.