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

本文介绍了一个使用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.youkuaiyun.com/detail/yysyangyangyangshan/5738491
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值