Le réseau pour les développeurs >
Forums - Accueil
>
Windows Presentation Foundation (WPF)
>
creating a 5-stars style rating control in XAML
creating a 5-stars style rating control in XAML
- Hi there,
I'm a designer getting to grips with WPF, I'm trying to make a 5/10-star rating slider type control, mirroring the functionality on my website http://www.blowersworld.com/ (not as rude as it sounds) - I have tried styling a slider control with stars instead of ticks, but can't seem to drill down to an individual tick mark.
I am starting to think about using a row of radio or toggle buttons. Anyone have any better ideas?
Thanks!
felix
Réponses
- Using a row of toggle buttons can be an option to go, here is an example:
<StackPanel x:Class="Mp3TagReader.RatingCell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel.Resources>
<Style x:Key="ratingButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Path Name="starPath" Fill="Gray" Data="M 9,0 L 7,6 L 0,6 L 6,11 L 4,17 L 9,12 L 14,17 L 12,11 L 18,6 L 11,6 L 9,0">
<Path.LayoutTransform>
<ScaleTransform ScaleX="0.8" ScaleY="0.8" />
</Path.LayoutTransform>
</Path>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="starPath" Property="Fill" Value="Gold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="1" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler" />
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="2" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler"/>
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="3" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler"/>
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="4" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler"/>
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="5" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler"/>
</StackPanel>
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Mp3TagReader
{
public partial class RatingCell : StackPanel
{
public RatingCell()
{
InitializeComponent();
}
public static readonly DependencyProperty RatingValueProperty = DependencyProperty.Register(
"RatingValue",
typeof(Int32),
typeof(RatingCell),
new PropertyMetadata(0, new PropertyChangedCallback(RatingValueChanged)));
public Int32 RatingValue
{
get
{
return (Int32)GetValue(RatingValueProperty);
}
set
{
if (value < 0)
{
SetValue(RatingValueProperty, 0);
}
else if (value > 5)
{
SetValue(RatingValueProperty, 5);
}
else
{
SetValue(RatingValueProperty, value);
}
}
}
private static void RatingValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
RatingCell parent = sender as RatingCell;
Int32 ratingValue = (Int32) e.NewValue;
UIElementCollection children = parent.Children;
ToggleButton button = null;
for (Int32 i = 0; i < ratingValue; i++)
{
button = children
as ToggleButton;
button.IsChecked = true;
}
for (Int32 i = ratingValue; i < children.Count; i++)
{
button = children
as ToggleButton;
button.IsChecked = false;
}
}
private void RatingButtonClickEventHandler(Object sender, RoutedEventArgs e)
{
ToggleButton button = sender as ToggleButton;
RatingValue = Int32.Parse((String)button.Tag);
}
}
}
This is a resuable user control, you can place it anywhere you like:
<cc:RatingCell RatingValue="5" />
Sheva
Toutes les réponses
- Using a row of toggle buttons can be an option to go, here is an example:
<StackPanel x:Class="Mp3TagReader.RatingCell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel.Resources>
<Style x:Key="ratingButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Path Name="starPath" Fill="Gray" Data="M 9,0 L 7,6 L 0,6 L 6,11 L 4,17 L 9,12 L 14,17 L 12,11 L 18,6 L 11,6 L 9,0">
<Path.LayoutTransform>
<ScaleTransform ScaleX="0.8" ScaleY="0.8" />
</Path.LayoutTransform>
</Path>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="starPath" Property="Fill" Value="Gold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="1" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler" />
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="2" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler"/>
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="3" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler"/>
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="4" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler"/>
<ToggleButton FocusVisualStyle="{x:Null}" Tag ="5" Width="20" Height="20" Style="{StaticResource ratingButton}" Click="RatingButtonClickEventHandler"/>
</StackPanel>
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Mp3TagReader
{
public partial class RatingCell : StackPanel
{
public RatingCell()
{
InitializeComponent();
}
public static readonly DependencyProperty RatingValueProperty = DependencyProperty.Register(
"RatingValue",
typeof(Int32),
typeof(RatingCell),
new PropertyMetadata(0, new PropertyChangedCallback(RatingValueChanged)));
public Int32 RatingValue
{
get
{
return (Int32)GetValue(RatingValueProperty);
}
set
{
if (value < 0)
{
SetValue(RatingValueProperty, 0);
}
else if (value > 5)
{
SetValue(RatingValueProperty, 5);
}
else
{
SetValue(RatingValueProperty, value);
}
}
}
private static void RatingValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
RatingCell parent = sender as RatingCell;
Int32 ratingValue = (Int32) e.NewValue;
UIElementCollection children = parent.Children;
ToggleButton button = null;
for (Int32 i = 0; i < ratingValue; i++)
{
button = children
as ToggleButton;
button.IsChecked = true;
}
for (Int32 i = ratingValue; i < children.Count; i++)
{
button = children
as ToggleButton;
button.IsChecked = false;
}
}
private void RatingButtonClickEventHandler(Object sender, RoutedEventArgs e)
{
ToggleButton button = sender as ToggleButton;
RatingValue = Int32.Parse((String)button.Tag);
}
}
}
This is a resuable user control, you can place it anywhere you like:
<cc:RatingCell RatingValue="5" />
Sheva Great sample! I made some minor changes to your code and fixed some small issues and blogged about it here: http://nickeandersson.blogs.com/blog/2008/02/a-rating-contro.html.
- God did I never reply to this? Sorry - I believe this was when I left one job to start another, how rude of me. Nonetheless I shall give it a whirl tomorrow and incorporate into my next projext

Thanks again! - This looks really useful thanks for posting
can Anyone tell Help me read / set the rating value in visual basic code. I have tried loads of things but not sure .
I think it works by assigning a style to each button so i need to do this in vb ?
Any help would be really good
cheers
luke

