Opening! WPF custom Controls (1)--Carousel Menu

Source: Internet
Author: User
Tags pow

Registered garden account for six months, have been trying to write something, but do not know where to write. The last one months in Wuxi, a company internship, the main thing to do is WPF-related development, although not previously exposed to WPF, but somehow learned C #, easy to understand.

Recently, a custom circular Carousel Menu control has been made, with the following effects:

Implementation process:

    1. Divide the child's nodes in a circle (the children's nodes here are all icons)
    2. Implement click the middle icon, peripheral icon rotation one week animation
    3. Implement the mouse click Drag to follow the rotation animation

Key code:

1. Divide the child nodes in a circle. Go through all the child nodes first, then subtract the middle icon, get the number of icons to divide the circumference, then get the split angle, and finally set the topproperty and leftproperty properties of each icon based on the angle, the outer circle radius, and the trigonometric functions.

1 //Evenly spaced circles showing middle and surrounding icons2         Private voidDividecircleonshowmenu ()3         {4             //Get child node5Uielementcollection children = This. Children;6 FrameworkElement F;7             8             //radius of Outer Circle9             DoubleOutcircleradius = This. width/2-iconwidthandheight/2;Ten  One             //Split degrees A             DoubleDivideequallyangle = the/(Children. Count-1); -  -              for(inti =0; I < children. Count; i++) the             { -f = children[i] asFrameworkElement; -                 //First middle icon -                 if(i = =0) +                 { -                     if(ShowMenu) +                     { A F.setvalue (Canvas.topproperty, Outcircleradius); at F.setvalue (Canvas.leftproperty, Outcircleradius); -                         if(Operatetype = =operateenum.mouseoperate) -                         { -F.mousedown + =F_mousedown; -                         } -                         Else in                         { -F.touchup + =F_touchup; to                         } +                     } -  the                     Else *                     { $F.setvalue (Canvas.topproperty, Outcircleradius-f.width/2);Panax NotoginsengF.setvalue (Canvas.leftproperty, Outcircleradius-f.width/2); -F.visibility =Visibility.hidden; the                     } +                 } A  the                 Else +                 { -                     //the angle of the inner angle is converted to radians $                     DoubleInnerangle = Divideequallyangle * (i-1) * Math.PI/ the; $  -                     //Top Distance -                     DoubleTopheight = Outcircleradius-math.cos (innerangle) *Outcircleradius; the  -                     //Left distanceWuyi                     DoubleLeftwidth = Math.sin (innerangle) *Outcircleradius; the  -                     if(Innerangle <= the) Wu                     { - F.setvalue (Canvas.topproperty, topheight); AboutF.setvalue (Canvas.leftproperty, Outcircleradius +leftwidth); $                     } -                     if(Innerangle > the) -                     { - F.setvalue (Canvas.topproperty, topheight); AF.setvalue (Canvas.leftproperty, Outcircleradius-leftwidth); +                     } the                 } -             } $}

2. Click the middle icon and the peripheral icon to rotate the animation one week. Here is the RotateTransform animation, the animation is very simple, is to rotate around the point. But you also have to set the rendertransformoriginof each icon, which is a relative point, with the upper-left corner of each icon as the origin of the coordinates, the downward and right positive, For example, set to (0.5,0.5) indicates that each icon rotates around its center point, which is rotated around its own lower-right corner. Here I choose to let the entire canvas around the center of their own rotation, and then let each icon around itself to reverse, you can achieve the direction of the icon is relatively unchanged. Finally I rotatenumber (rotation degree) is a custom dependency property that you can set yourself when the control is applied in the foreground XAML.

1  //Canvans Rotation2         Private voidRotateanimation (UIElement UIElement,Doublerotatenumber)3         {4RotateTransform RTF =NewRotateTransform ();5Uielement.rendertransform =rtf;6Uielement.rendertransformorigin =NewPoint (0.5,0.5);7 8             //defining animation paths and events9DoubleAnimation dbanimation =NewDoubleAnimation (0, Rotatenumber,Ten                 NewDuration (Timespan.fromseconds (rotatespeed))); One  A             //Start Animation -Rtf. BeginAnimation (Rotatetransform.angleproperty, dbanimation);

3. Implement the mouse drag to follow the rotation animation. This is mainly the Mousedown,mousemove and MouseUp events. The main MouseMove is to obtain the degree of rotation in each movement, as well as the direction of rotation of the judgment (clockwise or counterclockwise). I use the math knowledge of high school, the cosine formula of two vectors angle (yes, that's it, that's the way I can think of it now). After calculating the degree of rotation according to this formula, it is necessary to start judging the direction of rotation based on the quadrant of each click and end point.

  

//Drag icon Rotation event        Private voidRotate_mousemove (Objectsender, MouseEventArgs e) {Point Mafter= E.getposition ( This);//gets the coordinates in the mouse move processPoint N1=NewPoint (centerp.x-mbefore.x, CENTERP.Y-mbefore.y); Point N2=NewPoint (centerp.x-mafter.x, CENTERP.Y-mafter.y); //n1*n2            Doublen1n2 = N1. X * n2. X + N1. Yn2.            Y //the mold of the N1            DoubleN1mo = Math.sqrt (Math.pow (N1. X2) + Math.pow (N1. Y2)); //the mold of the N2            Doublen2mo = Math.sqrt (Math.pow (n2. X2) + Math.pow (n2. Y2)); //with a rotational angle.            DoubleRotatenum = Math.acos (n1n2/(N1MO *n2mo)); //relative coordinate Origin locationPoint PotM =NewPoint (); Potm.x= Mafter.x-centerp.x; Potm.y= Centerp.y-Mafter.y; Point PotD=NewPoint (); Potd.x= mbefore.x-centerp.x; Potd.y= Centerp.y-mbefore.y; //stop rotation when the mouse moves beyond the bounds            if(Mafter.x <0|| Mafter.x > This. Width | | Mafter.y <0|| Mafter.y > This. Height) { This. MouseMove-=Rotate_mousemove; }            Else            {                if(Getclockwise (PotD, PotM)) {Rotateang+=Rotatenum; }                Else{Rotateang-=Rotatenum; }            }            //performing rotation animationsIconrotateanimation (-Rotateang);        Canvansrotateanimation (Rotateang); }        /// <summary>        ///get a clockwise or counterclockwise/// </summary>        /// <param name= "PotD" >Press the coordinates</param>        /// <param name= "PotM" >Move coordinates</param>        /// <returns>True: Shun, False: Inverse</returns>        Private BOOLgetclockwise (Point PotD, point PotM) {if(Potm.y >=0&& Potd.y >=0)//one or two quadrant            {                returnPotm.x >=potd.x; }            if(Potm.y <0&& Potd.y <0)//three or four quadrant            {                returnPotm.x <=potd.x; }            if(Potm.x >=0&& potd.x >=0)//14 Quadrant            {                returnPotm.y <=Potd.y; }            if(Potm.x <0&& Potd.x <0)//two or three quadrant            {                returnPotm.y >=Potd.y; }            Else            {                return true; }        }    

Finally, the touch sliding function is added, in fact, the corresponding mouse event is replaced by the touch event is OK, but the effect may require a slight change in the implementation. Originally also want to make rotation belt inertia effect, only pity too dish, online resources also relatively few, can only Wugao and end. Now I feel that the development of WPF control is also very interesting, quite exercise people's logical thinking ability. This is the beginning of the article, and then the next!

Attach demo Source: Rotate Menu control

Opening! WPF custom Controls (1)--Carousel Menu

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.