zoukankan      html  css  js  c++  java
  • WP7自定义控件 评分控件

    最近在写一个新的APP程序,需要使用评分功能,WP的Toolkit里面没有包含,只能自己写一个了。

    评分控件要点

    评分控件已经很熟悉了,还是总结一下要点。

    1. 由10个(可配置)横排的五星组成,默认非高亮色(灰色)
    2. 得分由从左到右高亮(如红色,颜色可配置)显示得分数量的五星,控件能够提供获取和设置得分的属性。
    3. 可以点击其中一个五星修改评分。
    4. 为了提高触摸体验,支持拖动控件修改得分

    根据要点设计控件

    根据要点1设计控件布局

    Horizontal排列的StackPanel(包含在ItemsControl 控件内部) 和 绘制五星的Path 组成。

    最上面提供一个透明的Rectangle扩展触摸空间(WP只能在绘制的控件上触摸)。

    <ItemsControl x:Name="stars"> 
    <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
    <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
    <DataTemplate>
    <Path Data="M16,0 L19.77688,12.223213 L32.000001,12.222913 L22.111121,19.776973 L25.888544,32.000001 L16,24.445454 L6.1114563,32.000001 L9.88888,19.776973 L2.2971745E-08,12.222913 L12.22312,12.223213 z"
    Fill
    ="{Binding Fill}" HorizontalAlignment="Left" Height="32" Margin="1,0" Width="32"
    Stretch
    ="Fill" VerticalAlignment="Top" />
    </DataTemplate>
    </ItemsControl.ItemTemplate>
    </ItemsControl>
    <Rectangle Fill="#00000000"/>



    根据要点1、2设计控件属性

    Brush MarkedFill  选中了的五星刷子

    Brush UnMarkedFill 未选中的五星刷子

    int MaxStars 最大五星数量

    Marked 当前评价值

    根据要点2设计控件属性改变行为

    很简单获取Marked 然后将每个五星都修改一下颜色

    private void FillStars(int index) 
    {
    if (!VerifyValue(index)) return;

    for (int i = 0, length = starItems.Count; i < length; i++)
    {
    var star = starItems[i];
    if (i > index)
    {
    star.Fill = UnMarkedFill;
    }
    else
    {
    star.Fill = MarkedFill;
    }
    }

    }



    根据要点3、4设计控件触控行为

    将2个要点合并了,实现方法为:

    • 滑动前(点中): 修改为当前X轴的高亮位置
    • 滑动中:根据X轴变化高亮位置
    • 滑动完成(放开): 修改为当前X轴的高亮位置,并更新评分Marked 当前评价值

    通过五星的宽度可以获取X轴所在的五星

    代码如下:

    protected override void OnManipulationStarted(ManipulationStartedEventArgs e) 
    {
    e.Handled = true;
    UpdateStar(e.ManipulationOrigin);
    base.OnManipulationStarted(e);
    }

    protected override void OnManipulationDelta(ManipulationDeltaEventArgs e)
    {
    e.Handled = true;
    UpdateStar(e.ManipulationOrigin);
    base.OnManipulationDelta(e);
    }

    protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e)
    {
    e.Handled = true;
    var index = UpdateStar(e.ManipulationOrigin);
    if (VerifyValue(index)) { Marked = index + 1; }
    base.OnManipulationCompleted(e);
    }

    完整代码

    View Code
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;

    namespace KimiStudio.Controls
    {
    public class StarMark : Control
    {
    private ItemsControl stars;
    private const int StarSize = 34;
    private ObservableCollection<StarItem> starItems;

    #region DependencyPropertys
    public static readonly DependencyProperty MarkedFillProperty =
    DependencyProperty.Register("MarkedFill", typeof(Brush), typeof(StarMark),
    new PropertyMetadata(new SolidColorBrush(Colors.Red)));

    public static readonly DependencyProperty UnMarkedFillProperty =
    DependencyProperty.Register("UnMarkedFill", typeof(Brush), typeof(StarMark),
    new PropertyMetadata(new SolidColorBrush(Colors.DarkGray)));

    public static readonly DependencyProperty MaxStarsProperty =
    DependencyProperty.Register("MaxStars", typeof(int), typeof(StarMark),
    new PropertyMetadata(10));

    public static readonly DependencyProperty MarkedProperty =
    DependencyProperty.Register("Marked", typeof(int), typeof(StarMark),
    new PropertyMetadata(0, OnMarkedPropertyChanged));

    public int Marked
    {
    get { return (int)GetValue(MarkedProperty); }
    set { SetValue(MarkedProperty, value); }
    }

    public int MaxStars
    {
    get { return (int)GetValue(MaxStarsProperty); }
    set { SetValue(MaxStarsProperty, value); }
    }

    public Brush UnMarkedFill
    {
    get { return (Brush)GetValue(UnMarkedFillProperty); }
    set { SetValue(UnMarkedFillProperty, value); }
    }

    public Brush MarkedFill
    {
    get { return (Brush)GetValue(MarkedFillProperty); }
    set { SetValue(MarkedFillProperty, value); }
    }

    private static void OnMarkedPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs args)
    {
    var starMark = o as StarMark;
    if (starMark == null || args.NewValue == args.OldValue) return;

    starMark.SetMarked((int)args.NewValue);
    }

    #endregion

    public StarMark()
    {
    this.DefaultStyleKey = typeof(StarMark);
    }

    public override void OnApplyTemplate()
    {
    base.OnApplyTemplate();
    stars = (ItemsControl)GetTemplateChild("stars");


    starItems = new ObservableCollection<StarItem>();
    for (int i = 0, length = MaxStars; i < length; i++)
    {
    starItems.Add(new StarItem { Fill = UnMarkedFill });
    }
    stars.ItemsSource = starItems;
    SetMarked(Marked);
    }

    private void SetMarked(int value)
    {
    if (stars == null) return; ;
    FillStars(value - 1);
    }

    protected override void OnManipulationStarted(ManipulationStartedEventArgs e)
    {
    e.Handled = true;
    UpdateStar(e.ManipulationOrigin);
    base.OnManipulationStarted(e);
    }

    protected override void OnManipulationDelta(ManipulationDeltaEventArgs e)
    {
    e.Handled = true;
    UpdateStar(e.ManipulationOrigin);
    base.OnManipulationDelta(e);
    }

    protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e)
    {
    e.Handled = true;
    var index = UpdateStar(e.ManipulationOrigin);
    if (VerifyValue(index)) { Marked = index + 1; }
    base.OnManipulationCompleted(e);
    }

    private int UpdateStar(Point point)
    {
    int x = (int)point.X;
    int index = x / StarSize;
    FillStars(index);
    return index;
    }

    //SL可用
    //protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    //{
    // int x = (int)e.GetPosition(stars).X;
    // int index = x / StarSize;
    // FillStars(index);

    // if (VerifyValue(index)) { Marked = index + 1; }
    // base.OnMouseLeftButtonUp(e);
    //}


    private bool VerifyValue(int index)
    {
    if (index < 0 || index >= stars.Items.Count) return false;
    return true;
    }


    private void FillStars(int index)
    {
    if (!VerifyValue(index)) return;

    for (int i = 0, length = starItems.Count; i < length; i++)
    {
    var star = starItems[i];
    if (i > index)
    {
    star.Fill = UnMarkedFill;
    }
    else
    {
    star.Fill = MarkedFill;
    }
    }

    }




    public class StarItem : INotifyPropertyChanged
    {
    private Brush fill;

    public event PropertyChangedEventHandler PropertyChanged;

    public Brush Fill
    {
    get { return fill; }
    set
    {
    if (fill == value) return;
    fill = value;
    OnPropertyChanged("Fill");
    }
    }

    private void OnPropertyChanged(string propertyName)
    {
    var handler = PropertyChanged;
    if (handler == null) return;
    handler(this, new PropertyChangedEventArgs(propertyName));
    }
    }
    }
    }

    对应的Generic.xaml

    View Code
     <Style TargetType="local:StarMark">
    <Setter Property="Width" Value="340"/>
    <Setter Property="Height" Value="35"/>
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="local:StarMark">
    <Grid>
    <ItemsControl x:Name="stars">
    <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
    <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
    <DataTemplate>
    <Path Data="M16,0 L19.77688,12.223213 L32.000001,12.222913 L22.111121,19.776973 L25.888544,32.000001 L16,24.445454 L6.1114563,32.000001 L9.88888,19.776973 L2.2971745E-08,12.222913 L12.22312,12.223213 z"
    Fill
    ="{Binding Fill}" HorizontalAlignment="Left" Height="32" Margin="1,0" Width="32"
    Stretch
    ="Fill" VerticalAlignment="Top" />
    </DataTemplate>
    </ItemsControl.ItemTemplate>
    </ItemsControl>
    <Rectangle Fill="#00000000"/>
    </Grid>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>



     

  • 相关阅读:
    javascript实现非递归--归并排序
    javascript实现二分查找
    深入javascript作用域链到闭包
    c++学习笔记2--constexpr,类型别名,auto
    用 Numba 加速 Python 代码
    Django1和2的区别
    Git的使用
    文件锁fcntl
    Https原理
    Flask-Login
  • 原文地址:https://www.cnblogs.com/kiminozo/p/2390564.html
Copyright © 2011-2022 走看看