在Windows 8/WP/Silverlight/WPF下创建五角星

最近用到一个使用五角星做评级的小控件,用Path创建了一个五角星的控件,贴出代码及效果:

效果:

图片比较小,凑合看吧,贴出来现在使用的两个控件的代码。

第一个是单个的五角星控件,支持设置五角星大小、FillColor,Stroke等。

下面的代码是在Win8的程序下写的,如果在其他平台下,可以找到关键代码拷贝过去。

UcOneStarView.xaml

<UserControl
    x:Class="App1.Common.UserControls.UcOneStarView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1.Common.UserControls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <Grid Name="grdRoot"></Grid>
</UserControl>

UcOneStarView.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Shapes;

// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

namespace App1.Common.UserControls
{
    public sealed partial class UcOneStarView : UserControl
    {

        public int StarSize
        {
            get { return (int)GetValue(StarHeightProperty); }
            set { SetValue(StarHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarHeightProperty =
            DependencyProperty.Register("StarSize", typeof(int), typeof(UcOneStarView), new PropertyMetadata(100));

        public bool IsFill
        {
            get { return (bool)GetValue(IsFillProperty); }
            set { SetValue(IsFillProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsFill.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsFillProperty =
            DependencyProperty.Register("IsFill", typeof(bool), typeof(UcOneStarView), new PropertyMetadata(true));

        public Color StarFillColor
        {
            get { return (Color)GetValue(StarFillColorProperty); }
            set { SetValue(StarFillColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarFillColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarFillColorProperty =
            DependencyProperty.Register("StarFillColor", typeof(Color), typeof(UcOneStarView), new PropertyMetadata(Colors.Red));

        public Color StarStroke
        {
            get { return (Color)GetValue(StarStrokeProperty); }
            set { SetValue(StarStrokeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarStroke.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarStrokeProperty =
            DependencyProperty.Register("StarStroke", typeof(Color), typeof(UcOneStarView), new PropertyMetadata(Colors.White));

        public UcOneStarView()
        {
            this.InitializeComponent();

            this.Loaded += UcOneStarView_Loaded;
        }

        void UcOneStarView_Loaded(object sender, RoutedEventArgs e)
        {
            Path pathRoot = CreateAStar(StarSize, IsFill ? 100 : 0, StarFillColor, StarStroke);
            grdRoot.Children.Add(pathRoot);
        }

        /// <summary>
        /// 创建一个五角星的Path
        /// </summary>
        /// <param name="sizeBase"></param>
        /// <param name="percent">smaller than 100 && larger than 0</param>
        /// <param name="colorFill"></param>
        /// <param name="colorStroke"></param>
        private Path CreateAStar(double sizeBase, double percent, Color colorFill, Color colorStroke)
        {
            //定义Path
            Path pathRoot = new Path();
            pathRoot.Fill = new SolidColorBrush(colorFill);
            pathRoot.Stroke = new SolidColorBrush(colorStroke);

            PathGeometry pathData = new PathGeometry();
            PathFigureCollection pathFigureCollection = new PathFigureCollection();

            PathFigure pathFigure1 = new PathFigure();
            pathFigure1.StartPoint = new Point(sizeBase, 0);
            PathSegmentCollection pathSegments = new PathSegmentCollection();

            Point p1 = new Point(sizeBase, 0);
            //各定点连线中间部分长度的1/2
            double length1 = sizeBase / (Math.Tan(GetRadianByAngle(72d)) + Math.Tan(GetRadianByAngle(54d)));
            //圆中心到五角星各顶点连线的距离
            double length2 = sizeBase * Math.Sin(GetRadianByAngle(18d));
            Point p2 = new Point(sizeBase + length1, sizeBase - length2);
            Point p3 = new Point(sizeBase + length2 * Math.Tan(GetRadianByAngle(72d)), sizeBase - length2);
            Point p4 = new Point(p2.X + length1 * 2 * Math.Sin(GetRadianByAngle(18d)), p2.Y + length1 * 2 * Math.Cos(GetRadianByAngle(18d)));
            Point p5 = new Point(sizeBase + sizeBase * Math.Sin(GetRadianByAngle(36d)), sizeBase + sizeBase * Math.Cos(GetRadianByAngle(36d)));
            Point p6 = new Point(sizeBase, sizeBase + length2 / Math.Cos(GetRadianByAngle(36d)));
            Point p7 = new Point(sizeBase - sizeBase * Math.Sin(GetRadianByAngle(36d)), p5.Y);
            Point p8 = new Point(sizeBase - length2 / Math.Cos(GetRadianByAngle(36d)), p4.Y);
            Point p9 = new Point(sizeBase - sizeBase * Math.Sin(GetRadianByAngle(72d)), p3.Y);
            Point p10 = new Point(sizeBase - length1, sizeBase - length2);


            pathSegments.Add(new LineSegment() { Point = p2 });
            pathSegments.Add(new LineSegment() { Point = p3 });
            pathSegments.Add(new LineSegment() { Point = p4 });
            pathSegments.Add(new LineSegment() { Point = p5 });
            pathSegments.Add(new LineSegment() { Point = p6 });
            pathSegments.Add(new LineSegment() { Point = p7 });
            pathSegments.Add(new LineSegment() { Point = p8 });
            pathSegments.Add(new LineSegment() { Point = p9 });
            pathSegments.Add(new LineSegment() { Point = p10 });

            pathFigure1.Segments = pathSegments;
            pathFigure1.IsClosed = true;

            pathFigureCollection.Add(pathFigure1);
            pathData.Figures = pathFigureCollection;
            pathRoot.Data = pathData;

            if (percent > 0)
            {
                double boundWith = Math.Abs(p3.X - p9.X);
                double boundHeight = boundWith;
                //根据Star要显示的百分比来进行显示颜色
                Size rectSize = new Size(boundWith * percent / 100d, boundHeight);
                Rect rect = new Rect(new Point(p9.X, p1.Y), rectSize);
                pathRoot.Clip = new RectangleGeometry() { Rect = rect };
            }

            return pathRoot;
        }

        /// <summary>
        /// 把角度值转换成弧度
        /// </summary>
        /// <param name="angle">角度值</param>
        /// <returns>弧度值</returns>
        private double GetRadianByAngle(double angle)
        {
            return angle * Math.PI / 180d;
        }
    }
}

 

第二个是将每个五角星组合起来的控件

UcStarsView.xaml

<UserControl
    x:Class="App1.Common.UserControls.UcStarsView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1.Common.UserControls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <StackPanel Name="spRoot" Orientation="{Binding StarOrientation}">
    </StackPanel>
</UserControl>

 

UcStarsView.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Shapes;

// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

namespace App1.Common.UserControls
{
    public sealed partial class UcStarsView : UserControl
    {
        public int StarSize
        {
            get { return (int)GetValue(StarSizeProperty); }
            set { SetValue(StarSizeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarSize.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarSizeProperty =
            DependencyProperty.Register("StarSize", typeof(int), typeof(UcStarsView), new PropertyMetadata(100));

        public Color StarFillColor
        {
            get { return (Color)GetValue(StarFillColorProperty); }
            set { SetValue(StarFillColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarFillColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarFillColorProperty =
            DependencyProperty.Register("StarFillColor", typeof(Color), typeof(UcStarsView), new PropertyMetadata(Colors.Red));

        public Color StarStroke
        {
            get { return (Color)GetValue(StarStrokeProperty); }
            set { SetValue(StarStrokeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarStroke.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarStrokeProperty =
            DependencyProperty.Register("StarStroke", typeof(Color), typeof(UcStarsView), new PropertyMetadata(Colors.White));


        /// <summary>
        /// 大于0小于等于StarMaxNumber的整数
        /// </summary>
        public int Rating
        {
            get { return (int)GetValue(RatingProperty); }
            set
            {
                if (Rating < 0)
                {
                    throw new ArithmeticException("Rating should be larger than Zero.");
                }
                else
                {
                    if (Rating <= StarMaxNumber)
                    {
                        SetValue(RatingProperty, value);
                    }
                    else
                    {
                        throw new ArithmeticException("The number is larger than StarMaxNumber.");
                    }
                }
            }
        }

        // Using a DependencyProperty as the backing store for Rating.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RatingProperty =
            DependencyProperty.Register("Rating", typeof(int), typeof(UcStarsView), new PropertyMetadata(5));

        public Orientation StarOrientation
        {
            get { return (Orientation)GetValue(StarOrientationProperty); }
            set { SetValue(StarOrientationProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarOrientation.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarOrientationProperty =
            DependencyProperty.Register("StarOrientation", typeof(Orientation), typeof(UcStarsView), new PropertyMetadata(Orientation.Horizontal));


        public int StarMaxNumber
        {
            get { return (int)GetValue(StarMaxNumberProperty); }
            set { SetValue(StarMaxNumberProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarMaxNumber.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarMaxNumberProperty =
            DependencyProperty.Register("StarMaxNumber", typeof(int), typeof(UcStarsView), new PropertyMetadata(5));


        /// <summary>
        /// 五角星之间的距离
        /// </summary>
        public double StarMargin
        {
            get { return (double)GetValue(StarMarginProperty); }
            set { SetValue(StarMarginProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarMargin.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarMarginProperty =
            DependencyProperty.Register("StarMargin", typeof(double), typeof(UcStarsView), new PropertyMetadata(5));


        public UcStarsView()
        {
            this.InitializeComponent();

            this.DataContext = this;
            this.Loaded += UcStarsView_Loaded;
        }

        void UcStarsView_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < Rating; i++)
            {
                UcOneStarView star = CreateStar(true);
                star.StarFillColor = StarFillColor;
                star.Margin = new Thickness(0, 0, StarMargin, 0);
                spRoot.Children.Add(star);
            }

            for (int i = 0; i < StarMaxNumber - Rating; i++)
            {
                UcOneStarView star = CreateStar(false);
                star.StarFillColor = Colors.Transparent;
                star.Margin = new Thickness(0, 0, StarMargin, 0);
                spRoot.Children.Add(star);
            }
        }

        private UcOneStarView CreateStar(bool isFill)
        {
            UcOneStarView star = new UcOneStarView();
            star.StarSize = StarSize;
            star.StarStroke = StarStroke;
            star.IsFill = isFill;

            return star;
        }
    }
}http://go.microsoft.com/fwlink/?LinkId=234236

namespace App1.Common.UserControls
{
    public sealed partial class UcStarsView : UserControl
    {
        public int StarSize
        {
            get { return (int)GetValue(StarSizeProperty); }
            set { SetValue(StarSizeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarSize.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarSizeProperty =
            DependencyProperty.Register("StarSize", typeof(int), typeof(UcStarsView), new PropertyMetadata(100));

        public Color StarFillColor
        {
            get { return (Color)GetValue(StarFillColorProperty); }
            set { SetValue(StarFillColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarFillColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarFillColorProperty =
            DependencyProperty.Register("StarFillColor", typeof(Color), typeof(UcStarsView), new PropertyMetadata(Colors.Red));

        public Color StarStroke
        {
            get { return (Color)GetValue(StarStrokeProperty); }
            set { SetValue(StarStrokeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarStroke.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarStrokeProperty =
            DependencyProperty.Register("StarStroke", typeof(Color), typeof(UcStarsView), new PropertyMetadata(Colors.White));


        /// <summary>
        /// 大于0小于等于StarMaxNumber的整数
        /// </summary>
        public int Rating
        {
            get { return (int)GetValue(RatingProperty); }
            set
            {
                if (Rating < 0)
                {
                    throw new ArithmeticException("Rating should be larger than Zero.");
                }
                else
                {
                    if (Rating <= StarMaxNumber)
                    {
                        SetValue(RatingProperty, value);
                    }
                    else
                    {
                        throw new ArithmeticException("The number is larger than StarMaxNumber.");
                    }
                }
            }
        }

        // Using a DependencyProperty as the backing store for Rating.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RatingProperty =
            DependencyProperty.Register("Rating", typeof(int), typeof(UcStarsView), new PropertyMetadata(5));

        public Orientation StarOrientation
        {
            get { return (Orientation)GetValue(StarOrientationProperty); }
            set { SetValue(StarOrientationProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarOrientation.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarOrientationProperty =
            DependencyProperty.Register("StarOrientation", typeof(Orientation), typeof(UcStarsView), new PropertyMetadata(Orientation.Horizontal));


        public int StarMaxNumber
        {
            get { return (int)GetValue(StarMaxNumberProperty); }
            set { SetValue(StarMaxNumberProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarMaxNumber.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarMaxNumberProperty =
            DependencyProperty.Register("StarMaxNumber", typeof(int), typeof(UcStarsView), new PropertyMetadata(5));


        /// <summary>
        /// 五角星之间的距离
        /// </summary>
        public double StarMargin
        {
            get { return (double)GetValue(StarMarginProperty); }
            set { SetValue(StarMarginProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StarMargin.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StarMarginProperty =
            DependencyProperty.Register("StarMargin", typeof(double), typeof(UcStarsView), new PropertyMetadata(5));


        public UcStarsView()
        {
            this.InitializeComponent();

            this.DataContext = this;
            this.Loaded += UcStarsView_Loaded;
        }

        void UcStarsView_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < Rating; i++)
            {
                UcOneStarView star = CreateStar(true);
                star.StarFillColor = StarFillColor;
                star.Margin = new Thickness(0, 0, StarMargin, 0);
                spRoot.Children.Add(star);
            }

            for (int i = 0; i < StarMaxNumber - Rating; i++)
            {
                UcOneStarView star = CreateStar(false);
                star.StarFillColor = Colors.Transparent;
                star.Margin = new Thickness(0, 0, StarMargin, 0);
                spRoot.Children.Add(star);
            }
        }

        private UcOneStarView CreateStar(bool isFill)
        {
            UcOneStarView star = new UcOneStarView();
            star.StarSize = StarSize;
            star.StarStroke = StarStroke;
            star.IsFill = isFill;

            return star;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值