WPF-22:WPF实现五角星绘制及评级控件

类似淘宝的评级控件在程序业务中使用比较多,尤其是对于电子商务方面的编程。最近做了这样的一个小功能,使用WPF实现。但是对于五角星的绘制部分的代码(包括计算五个点),可以应用于Winform,ASP.NET等。下面来看代码的实现。
该项目名称:TestFivePointStarLikeTaobao。这个项目如下图,

1、五角星的绘制。
绘制五角星,主要是要根据半径获得五个点。
 /// <summary>
        /// 根据半径和圆心确定五个点
        /// </summary>
        /// <param name="center"></param>
        /// <returns></returns>
        private PointCollection GetFivePoint(Point center)
        {
            double r = 半径;


            double h1 = r * Math.Sin(18 * Math.PI / 180);


            double h2 = r * Math.Cos(18 * Math.PI / 180);


            double h3 = r * Math.Sin(36 * Math.PI / 180);


            double h4 = r * Math.Cos(36 * Math.PI / 180);


            Point p1 = new Point(r, center.X);


            Point p2 = new Point(r - h2, r - h1);


            Point p3 = new Point(r - h3, r + h4);


            Point p4 = new Point(r + h3, p3.Y);


            Point p5 = new Point(r + h2, p2.Y);


            List<Point> values = new List<Point>() { p1, p3, p5, p2, p4 };


            PointCollection pcollect = new PointCollection(values);


            return pcollect;
        }
WPF这个类如下,
   public class FivePointStar:UserControl
    {
        private double radius = 20;


        private double currentPart = 1;


        private Brush selectBackground = new SolidColorBrush(Colors.YellowGreen);


        private Brush unselectBackgroud = new SolidColorBrush(Colors.DarkGray);


        /// <summary>
        /// 半径
        /// </summary>
        public double Radius
        {
            get 
            {
               object result = GetValue(RadiusProperty);


                if(result==null)
                {
                    return radius;
                }


                return (double)result;
            }


            set
            {
                SetValue(RadiusProperty, value);


                this.InvalidateVisual();
            }
        }


        public static  DependencyProperty RadiusProperty =
           DependencyProperty.Register("Radius", typeof(double), 
           typeof(FivePointStar), new UIPropertyMetadata());


        /// <summary>
        /// 当前是否是一颗星
        /// </summary>
        public double CurrentPart
        {
            get
            {
                object result = GetValue(CurrentPartProperty);


                if (result == null)
                {
                    return currentPart;
                }
                return (double)result;
            }


            set
            {
                SetValue(CurrentPartProperty, value);


                this.InvalidateVisual();
            }
        }


        public static  DependencyProperty CurrentPartProperty =
           DependencyProperty.Register("CurrentPart", typeof(double), 
           typeof(FivePointStar), new UIPropertyMetadata());


        /// <summary>
        /// 选中颜色
        /// </summary>
        public Brush SelectBackground
        {
            get
            {
                object result = GetValue(SelectBackgroundProperty);


                if (result == null)
                {
                    return selectBackground;
                }


                return (Brush)result;
            }


            set
            {
                SetValue(SelectBackgroundProperty, value);
            }
        }


        public static  DependencyProperty SelectBackgroundProperty =
           DependencyProperty.Register("SelectBackground", typeof(Brush), 
           typeof(FivePointStar), new UIPropertyMetadata());


        /// <summary>
        /// 未选中颜色
        /// </summary>
        public Brush UnSelectBackground
        {
            get
            {
                object result = GetValue(UnSelectBackgroundProperty);


                if (result == null)
                {
                    return unselectBackgroud;
                }


                return (Brush)result;
            }


            set
            {
                SetValue(UnSelectBackgroundProperty, value);
            }
        }


        public static  DependencyProperty UnSelectBackgroundProperty =
           DependencyProperty.Register("UnSelectBackground", typeof(Brush), 
           typeof(FivePointStar), new UIPropertyMetadata());




        public FivePointStar()
            : base()
        {
            this.Loaded += new RoutedEventHandler(FivePointStar_Loaded);
        }


        void FivePointStar_Loaded(object sender, RoutedEventArgs e)
        {
            this.MinHeight = Radius * 2;


            this.MaxHeight = Radius * 2;


            this.MinWidth = Radius * 2;


            this.MaxWidth = Radius * 2;


            this.Background = Brushes.Transparent;
        }


        protected override void OnRender(System.Windows.Media.DrawingContext dc)
        {
            base.OnRender(dc);


            Point center = new Point();


            PointCollection Points = GetFivePoint(center);


            Canvas ca = new Canvas();


            Polygon plg = new Polygon();


            plg.Points = Points;


            plg.Stroke = Brushes.Transparent;


            plg.StrokeThickness = 2;


            if (CurrentPart == 1)
            {
                plg.Fill = this.SelectBackground;
            }
            else
            {
                plg.Fill = this.UnSelectBackground;
            }


            plg.FillRule = FillRule.Nonzero;


            ca.Children.Add(plg);




            this.Content = ca;






            //Brush b = new SolidColorBrush(Colors.Yellow);


            //Pen p = new Pen(b, 2);


            //var path = new Path();


            //var gc = new GeometryConverter();


            //path.Data = (Geometry)gc.ConvertFromString(string.Format("M {0} {1} {2} {3} {4} Z",
            //    Points[0], Points[1], Points[2], Points[3], Points[4]));


            //path.Fill = Brushes.Yellow;


            //dc.DrawGeometry(b, p, path.Data);
        }


        /// <summary>
        /// 根据半径和圆心确定五个点
        /// </summary>
        /// <param name="center"></param>
        /// <returns></returns>
        private PointCollection GetFivePoint(Point center)
        {
            double r = Radius;


            double h1 = r * Math.Sin(18 * Math.PI / 180);


            double h2 = r * Math.Cos(18 * Math.PI / 180);


            double h3 = r * Math.Sin(36 * Math.PI / 180);


            double h4 = r * Math.Cos(36 * Math.PI / 180);


            Point p1 = new Point(r, center.X);


            Point p2 = new Point(r - h2, r - h1);


            Point p3 = new Point(r - h3, r + h4);


            Point p4 = new Point(r + h3, p3.Y);


            Point p5 = new Point(r + h2, p2.Y);


            List<Point> values = new List<Point>() { p1, p3, p5, p2, p4 };


            PointCollection pcollect = new PointCollection(values);


            return pcollect;
        }
    }
可以直接将该类作为自定义控件放置于容器控件上。效果如下,

2、绘制一组五角星。
WPF代码,
界面代码:
<UserControl x:Class="TestFivePointStarLikeTaobao.FivePointStarGroup"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:TestFivePointStarLikeTaobao"
             mc:Ignorable="d">
    <Grid x:Name="groupGrid" Background="Transparent">
        <ListBox x:Name="lsbchildCategory" ItemsSource="{Binding ChildCategoryList,IsAsync=True}"
                     Background="WhiteSmoke" BorderThickness="0">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <local:FivePointStar Radius="{Binding Radius}" CurrentPart="{Binding CurrentValue}" Tag="{Binding ID}"
                                         SelectBackground="{Binding SelectBackground}" UnSelectBackground="{Binding UnselectBackgroud}"
                                         MouseDown="FivePointStar_MouseDown"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel  VerticalAlignment="Center" Orientation="Horizontal" HorizontalAlignment="Center"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </Grid>
</UserControl>
后台代码:
   /// <summary>
    /// FivePointStarGroup.xaml 的交互逻辑
    /// </summary>
    public partial class FivePointStarGroup : UserControl
    {
        private double radius = 20;


        private double itemsCount = 5;


        private double selectCount = 5;


        private Brush selectBackground = new SolidColorBrush(Colors.YellowGreen);


        private Brush unselectBackgroud = new SolidColorBrush(Colors.DarkGray);


          /// <summary>
        /// 五角星半径
        /// </summary>
        public double Radius
        {
            get 
            {
               object result = GetValue(RadiusProperty);


                if(result==null)
                {
                    return radius;
                }


                return (double)result;
            }


            set
            {
                SetValue(RadiusProperty, value);
            }
        }


        public static  DependencyProperty RadiusProperty =
           DependencyProperty.Register("Radius", typeof(double), 
           typeof(FivePointStarGroup), new UIPropertyMetadata());


        /// <summary>
        /// 五角星个数
        /// </summary>
        public double ItemsCount
        {
            get
            {
                object result = GetValue(ItemsCountProperty);


                if (result == null)
                {
                    return  itemsCount;
                }


                return (double)result;
            }


            set
            {
                SetValue(ItemsCountProperty, value);


                InitialData();


                this.InvalidateVisual();
            }
        }


        public static  DependencyProperty ItemsCountProperty =
           DependencyProperty.Register("ItemsCount", typeof(double), 
           typeof(FivePointStar), new UIPropertyMetadata());


        /// <summary>
        /// 选中的五角星个数
        /// </summary>
        public double SelectCount
        {
            get
            {
                object result = GetValue(SelectCountProperty);


                if (result == null)
                {
                    return selectCount;
                }


                return (double)result;
            }


            set
            {
                SetValue(SelectCountProperty, value);


                InitialData();


                this.InvalidateVisual();
            }
        }


        public static  DependencyProperty SelectCountProperty =
           DependencyProperty.Register("SelectCount", typeof(double), 
           typeof(FivePointStar), new UIPropertyMetadata());


        public event RoutedEventHandler SelectCountChangeEvent
        {
            add { AddHandler(SelectCountChangePropertyEvent, value); }


            remove { RemoveHandler(SelectCountChangePropertyEvent, value); }
        }


        /// <summary>
        /// 选中颜色
        /// </summary>
        public Brush SelectBackground
        {
            get
            {
                object result = GetValue(SelectBackgroundProperty);


                if (result == null)
                {
                    return selectBackground;
                }


                return (Brush)result;
            }


            set
            {
                SetValue(SelectBackgroundProperty, value);
            }
        }


        public static  DependencyProperty SelectBackgroundProperty =
           DependencyProperty.Register("SelectBackground", typeof(Brush), 
           typeof(FivePointStarGroup), new UIPropertyMetadata());


        /// <summary>
        /// 未选中颜色
        /// </summary>
        public Brush UnSelectBackground
        {
            get
            {
                object result = GetValue(UnSelectBackgroundProperty);


                if (result == null)
                {
                    return unselectBackgroud;
                }


                return (Brush)result;
            }


            set
            {
                SetValue(UnSelectBackgroundProperty, value);
            }
        }


        public static  DependencyProperty UnSelectBackgroundProperty =
           DependencyProperty.Register("UnSelectBackground", typeof(Brush), 
           typeof(FivePointStarGroup), new UIPropertyMetadata());


        public static  RoutedEvent SelectCountChangePropertyEvent =
             EventManager.RegisterRoutedEvent("SelectCountChangeEvent", 
             RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Control));


        public FivePointStarGroup()
        {
            InitializeComponent();


            this.Loaded += new RoutedEventHandler(FivePointStarGroup_Loaded);
        }


        void FivePointStarGroup_Loaded(object sender, RoutedEventArgs e)
        {
            InitialData();
        }


        private void InitialData()
        {
            List<FivePointStarModel> list = new List<FivePointStarModel>();


            int count = Convert.ToInt32(this.ItemsCount);


            if (count <= 0)
            {
                count = Convert.ToInt32(this.itemsCount);
            }


            for (int i = 0; i < count; i++)
            {
                FivePointStarModel item = new FivePointStarModel();


                item.ID = i + 1;


                item.Radius = Radius;


                item.SelectBackground = SelectBackground;


                item.UnselectBackgroud = UnSelectBackground;


                //在此设置星形显示的颜色
                if ((i+1) > SelectCount)
                {
                    item.CurrentValue = 0;
                }


                list.Add(item);
            }


            this.lsbchildCategory.ItemsSource = list;
        }


        private void FivePointStar_MouseDown(object sender, MouseButtonEventArgs e)
        {
            FivePointStar m = sender as FivePointStar;


            if (m == null)
            {
                return;
            }


            int index = Convert.ToInt32(m.Tag);


            this.SelectCount = index;


            RaiseEvent(new RoutedEventArgs(SelectCountChangePropertyEvent, sender)); 
        }
    }
控制单个五角星属性的绑定的类:
    public class FivePointStarModel: INotifyPropertyChanged
    {
        public void OnPropertyChanged(string name)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
   
        private int id;


        private double radius = 20;


        private double currentValue = 1;


        private Brush selectBackground = new SolidColorBrush(Colors.GreenYellow);


        private Brush unselectBackgroud = new SolidColorBrush(Colors.DarkGray);


        public int ID
        {
            get { return id; }


            set
            {
                id = value;


                this.OnPropertyChanged("Radius");
            }
        }


        public double Radius
        {
            get { return radius; }


            set 
            { 
                radius = value;


                this.OnPropertyChanged("Radius");
            }
        }


        public double CurrentValue
        {
            get { return currentValue; }


            set 
            {
                currentValue = value;


                this.OnPropertyChanged("CurrentValue");
            }
        }


        public Brush SelectBackground
        {
            get { return selectBackground; }


            set
            {
                selectBackground = value;


                this.OnPropertyChanged("SelectBackground");
            }
        }


        public Brush UnselectBackgroud
        {
            get { return unselectBackgroud; }


            set
            {
                unselectBackgroud = value;


                this.OnPropertyChanged("UnselectBackgroud");
            }
        }
    }
上面就是五角星和多个五角星的全部代码。
调用:
<Window x:Class="TestFivePointStarLikeTaobao.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="446" Width="849" xmlns:my="clr-namespace:TestFivePointStarLikeTaobao">
    <Grid>
        <my:FivePointStarGroup HorizontalAlignment="Stretch" Margin="62,27,59,254" x:Name="fivePointStarGroup1" 
                               VerticalAlignment="Stretch" SelectBackground="GreenYellow" Radius="30"
                               UnSelectBackground="DarkGray" ItemsCount="5" SelectCount="5" />
        <TextBox Height="30" HorizontalAlignment="Left" Margin="202,232,0,0" Name="textBox1" VerticalAlignment="Top"
                 Width="120"  FontSize="18" />
        <Button Content="设 置" Height="46" HorizontalAlignment="Left" Margin="365,192,0,0" Name="button1" 
                VerticalAlignment="Top" Width="142" FontSize="18" Click="button1_Click" />
        <TextBox Height="30" HorizontalAlignment="Left" Margin="202,159,0,0" Name="textBox2" VerticalAlignment="Top" 
                 Width="120" FontSize="18"/>
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="136,232,0,0" Name="textBlock1" Text="选 中:" 
                   VerticalAlignment="Top" FontSize="18"/>
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="136,159,0,0" Name="textBlock2" Text="总 数:" 
                   VerticalAlignment="Top"  FontSize="18"/>
        <my:FivePointStar HorizontalAlignment="Left" Margin="576,240,0,0" x:Name="fivePointStar1" VerticalAlignment="Top"
                          Height="20" Width="154" Radius="20" CurrentPart="1" />
    </Grid>
</Window>


/// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();


            InitialData();


            this.fivePointStarGroup1.SelectCountChangeEvent += 
                new RoutedEventHandler(fivePointStarGroup1_SelectCountChangeEvent);
        }


        private void InitialData()
        {
            this.textBox1.Text = this.fivePointStarGroup1.SelectCount.ToString();


            this.textBox2.Text = this.fivePointStarGroup1.ItemsCount.ToString();
        }


        void fivePointStarGroup1_SelectCountChangeEvent(object sender, RoutedEventArgs e)
        {
            InitialData();
        }


        private void button1_Click(object sender, RoutedEventArgs e)
        {
            int selectCount = Convert.ToInt32(this.textBox1.Text);


            int allCount = Convert.ToInt32(this.textBox2.Text);


            if (allCount < selectCount)
            {
                MessageBox.Show("参数设置错误!");


                return;
            }


            this.fivePointStarGroup1.ItemsCount = allCount;


            this.fivePointStarGroup1.SelectCount = selectCount;
        }
    } 
效果如图,

代码下载:
http://download.csdn.net/detail/yysyangyangyangshan/5738491
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值