Le réseau pour les développeurs > Forums - Accueil > Windows Presentation Foundation (WPF) > creating a 5-stars style rating control in XAML
Poser une questionPoser une question
 

Traitéecreating a 5-stars style rating control in XAML

  • vendredi 3 août 2007 10:14felixthehat Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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

  • vendredi 3 août 2007 10:57Zhou Yong Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée
    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 = childrenIdea as ToggleButton;
    button.IsChecked = true;
    }

    for (Int32 i = ratingValue; i < children.Count; i++)
    {
    button = childrenIdea 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

  • vendredi 3 août 2007 10:57Zhou Yong Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     Traitée
    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 = childrenIdea as ToggleButton;
    button.IsChecked = true;
    }

    for (Int32 i = ratingValue; i < children.Count; i++)
    {
    button = childrenIdea 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


  • mercredi 20 février 2008 19:01Nicke Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     

    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.

  • mercredi 20 février 2008 21:18felixthehat Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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 Smile

    Thanks again!
  • dimanche 7 juin 2009 12:35ls782 Médailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateurMédailles de l'utilisateur
     
    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