类似淘宝的评级控件在程序业务中使用比较多,尤其是对于电子商务方面的编程。最近做了这样的一个小功能,使用WPF实现。但是对于五角星的绘制部分的代码(包括计算五个点),可以应用于Winform,ASP.NET等。下面来看代码的实现。
该项目名称:TestFivePointStarLikeTaobao。这个项目如下图,
1、五角星的绘制。
绘制五角星,主要是要根据半径获得五个点。
2、绘制一组五角星。
WPF代码,
界面代码:
调用:
代码下载:
http://download.csdn.net/detail/yysyangyangyangshan/5738491
该项目名称: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