• 评分控件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>

  • 相关阅读:
    eclipse maven POM 第一行提示异常Could not initialize class org.apache.maven.plugin.war.util.WebappStructureSerializer
    Tomcat搭建HTTP文件下载服务器
    Hui datetimepicker 插件不显示左右箭头问题
    【Python】拷贝&列表
    【Python】Python赋值引用、浅拷贝、深拷贝
    【Python】列表的复制
    【Python】电脑安装了多个版本Python,如何切换;
    【Python】定义类、创建类实例
    【Python】白名单方式净化
    c++ 对外提供头文件的模式
  • 原文地址:https://www.cnblogs.com/androllen/p/2837701.html
Copyright © 2020-2023  润新知