WPF 实现大转盘抽奖~

  接着上一篇圆形控件

01

代码如下

一、创建 PrizeItemControl.cs代码如下。

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WPFDevelopers.Controls
{
    [TemplatePart(Name = RotateTransformTemplateName, Type = typeof(RotateTransform))]
    public class PrizeItemControl : Control
    {
        private static readonly Type _typeofSelf = typeof(PrizeItemControl);
        private const string RotateTransformTemplateName = "PART_RotateTransform";
        private RotateTransform _angleRotateTransform;
        public double Angle
        {
            get { return (double)GetValue(AngleProperty); }
            set { SetValue(AngleProperty, value); }
        }

        public static readonly DependencyProperty AngleProperty =
            DependencyProperty.Register("Angle", typeof(double), typeof(PrizeItemControl), new UIPropertyMetadata(OnAngleChanged));

        private static void OnAngleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PrizeItemControl control = (PrizeItemControl)d;
            control.UpdateAngle();
        }
        void UpdateAngle()
        {
            if (_angleRotateTransform == null) return;
            _angleRotateTransform.Angle = Angle;
        }
        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }

        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title", typeof(string), typeof(PrizeItemControl), new PropertyMetadata(string.Empty));


        public Brush BackgroundColor
        {
            get { return (Brush)GetValue(BackgroundColorProperty); }
            set { SetValue(BackgroundColorProperty, value); }
        }
        public static readonly DependencyProperty BackgroundColorProperty =
           DependencyProperty.Register("BackgroundColor", typeof(Brush), typeof(PrizeItemControl), new PropertyMetadata(null));


        static PrizeItemControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(_typeofSelf, new FrameworkPropertyMetadata(_typeofSelf));
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _angleRotateTransform = GetTemplateChild(RotateTransformTemplateName) as RotateTransform;
            UpdateAngle();
        }


    }
}

二、创建 DrawPrize.cs代码如下。

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;


namespace WPFDevelopers.Controls
{
    [TemplatePart(Name = BorderTemplateName, Type = typeof(Border))]
    [TemplatePart(Name = RotateTransformTemplateName, Type = typeof(RotateTransform))]
    public class DrawPrize : ListBox
    {
        private const string BorderTemplateName = "PART_Border";
        private const string RotateTransformTemplateName = "PART_ItemsControlAngle";

        private Border _border;
        private RotateTransform _rotateTransform;



        public List<int> ListAngle
        {
            get { return (List<int>)GetValue(ListAngleProperty); }
            set { SetValue(ListAngleProperty, value); }
        }

        public static readonly DependencyProperty ListAngleProperty =
            DependencyProperty.Register("ListAngle", typeof(List<int>), typeof(DrawPrize), new PropertyMetadata());


        private int value;

        static DrawPrize()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DrawPrize), new FrameworkPropertyMetadata(typeof(DrawPrize)));
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            AlternationCount = 8;
            _border = GetTemplateChild(BorderTemplateName) as Border;
            _rotateTransform = GetTemplateChild(RotateTransformTemplateName) as RotateTransform;
            _border.MouseDown += _border_MouseDown;

        }
       
        private void _border_MouseDown(object sender, MouseButtonEventArgs e)
        {
            _border.IsEnabled = false;
            _border.Cursor = Cursors.None;
            var random = new Random();
            var to = random.Next(0, 8);
            var doubleAnimation = new DoubleAnimationUsingKeyFrames();
            value = ListAngle[to];
            
            var splineDoubleKey1 = new SplineDoubleKeyFrame
            {
                KeyTime = TimeSpan.FromSeconds(0),
                Value = value % 360,
            };
            var splineDoubleKey2 = new SplineDoubleKeyFrame
            {
                KeyTime = TimeSpan.FromMilliseconds(1000),
                Value = 360,
            };
            var splineDoubleKey3 = new SplineDoubleKeyFrame
            {
                KeyTime = TimeSpan.FromMilliseconds(2000),
                Value = 1230,
            };
            var splineDoubleKey4 = new SplineDoubleKeyFrame
            {
                KeyTime = TimeSpan.FromMilliseconds(4000),
                Value = value,
                KeySpline = new KeySpline(0, 0, 0, 1)
            };
            doubleAnimation.KeyFrames.Add(splineDoubleKey1);
            doubleAnimation.KeyFrames.Add(splineDoubleKey2);
            doubleAnimation.KeyFrames.Add(splineDoubleKey3);
            doubleAnimation.KeyFrames.Add(splineDoubleKey4);
            doubleAnimation.Completed += (s1,e1)=> { _border.IsEnabled = true; _border.Cursor = Cursors.Hand; };
            _rotateTransform.BeginAnimation(RotateTransform.AngleProperty, doubleAnimation);
        }
    }
}

三、创建 PrizeItemControl.xaml代码如下。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="clr-namespace:WPFDevelopers.Controls"
                    xmlns:convert="clr-namespace:WPFDevelopers.Converts">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
        <ResourceDictionary Source="Basic/Animations.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="{x:Type controls:PrizeItemControl}" BasedOn="{StaticResource ControlBasicStyle}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="controls:PrizeItemControl">
                    <Grid VerticalAlignment="Top">
                        <Grid.RenderTransform>
                            <RotateTransform x:Name="PART_RotateTransform" 
                                             Angle="{TemplateBinding Angle}" 
                                             CenterX="200" CenterY="200"></RotateTransform>
                        </Grid.RenderTransform>
                        <Path x:Name="PART_Path" Data="{StaticResource PathSector}" 
                                  Fill="{TemplateBinding BackgroundColor}" VerticalAlignment="Center"/>
                        <TextBlock Text="{TemplateBinding Title}" 
                                   RenderTransformOrigin="0.5,0.5"
                                   Margin="50,100,0,0" 
                                   Foreground="{DynamicResource WhiteSolidColorBrush}"
                                   FontSize="16"
                                   FontWeight="DemiBold"
                                   HorizontalAlignment="Left" 
                                   VerticalAlignment="Center" >
                            <TextBlock.RenderTransform>
                                <RotateTransform Angle="-70"/>
                            </TextBlock.RenderTransform>
                        </TextBlock>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <convert:DrawPrizeIndexToColor x:Key="drawPrizeIndexToColor"/>
    <Style TargetType="{x:Type controls:DrawPrize}" BasedOn="{StaticResource ControlBasicStyle}">
        <Setter Property="Width" Value="400"/>
        <Setter Property="Height" Value="400"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:DrawPrize}">
                    <Grid>
                        <ItemsControl x:Name="PART_ItemsControl" ItemsSource="{TemplateBinding ItemsSource}"
                                      AlternationCount="{TemplateBinding AlternationCount}"
                                      Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
                                      RenderTransformOrigin=".5,.5">
                            <ItemsControl.RenderTransform>
                                <RotateTransform x:Name="PART_ItemsControlAngle" Angle="0"/>
                            </ItemsControl.RenderTransform>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <controls:PrizeItemControl Angle="{Binding Angle}"
                                                               BackgroundColor="{Binding Path=(ItemsControl.AlternationIndex),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource drawPrizeIndexToColor}}" 
                                                               Title="{Binding Title}">
                                      
                                    </controls:PrizeItemControl>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <Grid/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                        </ItemsControl>
                        <Path Data="M562.8 77.6c-31.4-18.1-70.1-18.1-101.5 0C215.4 219.5 64 481.8 64 765.6c0 36.3 19.4 69.8 50.8 87.9 245.8 141.9 548.7 141.9 794.5 0 31.4-18.1 50.8-51.7 50.8-87.9-0.1-283.8-151.5-546.1-397.3-688z"
                              Stretch="Fill" 
                              Fill="#fbb845"
                              Width="40" Height="120"
                              Margin="0,0,0,50">
                            
                        </Path>

                        <Border Background="#fbb845" x:Name="PART_Border"
                                Width="100" Height="100"
                                CornerRadius="50"
                                Cursor="Hand">
                            <TextBlock Text="GO" 
                           Foreground="{DynamicResource WhiteSolidColorBrush}"
                           FontSize="40"
                           FontWeight="DemiBold"
                           VerticalAlignment="Center"
                           HorizontalAlignment="Center"/>
                        </Border>

                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

四、创建 DrawPrizeExample.xaml代码如下。

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.DrawPrizeExample"
             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:WPFDevelopers.Samples.ExampleViews"
             xmlns:wpfdev="https://github.com/yanjinhuagood/WPFDevelopers"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <StackPanel>
        
        <wpfdev:DrawPrize x:Name="PART_DrawPrize" ItemsSource="{Binding MenuArray,RelativeSource={RelativeSource AncestorType=local:DrawPrizeExample}}"
                          ListAngle="{Binding ListAngle,RelativeSource={RelativeSource AncestorType=local:DrawPrizeExample}}">
            
        </wpfdev:DrawPrize>
    </StackPanel>
</UserControl>

五、 DrawPrizeExample.xaml.cs代码如下。

using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using WPFDevelopers.Samples.Models;

namespace WPFDevelopers.Samples.ExampleViews
{
    /// <summary>
    /// DrawPrizeExample.xaml 的交互逻辑
    /// </summary>
    public partial class DrawPrizeExample : UserControl
    {
        public IEnumerable MenuArray
        {
            get { return (IEnumerable)GetValue(MenuArrayProperty); }
            set { SetValue(MenuArrayProperty, value); }
        }

        public static readonly DependencyProperty MenuArrayProperty =
            DependencyProperty.Register("MenuArray", typeof(IEnumerable), typeof(DrawPrizeExample), new PropertyMetadata(null));

      
        public List<int> ListAngle
        {
            get { return (List<int>)GetValue(ListAngleProperty); }
            set { SetValue(ListAngleProperty, value); }
        }

        public static readonly DependencyProperty ListAngleProperty =
            DependencyProperty.Register("ListAngle", typeof(List<int>), typeof(DrawPrizeExample), new PropertyMetadata());


       
        public DrawPrizeExample()
        {
            InitializeComponent();
            this.Loaded += DrawPrizeExample_Loaded;
        }

        private void DrawPrizeExample_Loaded(object sender, RoutedEventArgs e)
        {
            ListAngle = new List<int>();
            var menuItemModels = new List<MenuItemModel>();
            var angle = 0;
            var anglePrize = 2000;
            for (int i = 0; i <= 7; i++)
            {
                var prizeTitle = i == 0 ? "谢谢参与" : $"{i}等奖";
                angle += 45;
                anglePrize += 45;
                ListAngle.Add(anglePrize);
                menuItemModels.Add(new MenuItemModel { Angle = angle, Title = prizeTitle});
            }

            MenuArray = menuItemModels;
        }
       
    }
}

02


效果预览

如果你喜欢这个封面的话,欢迎转发给身边的朋友领取。

感谢大家一直以来的支持,祝你在新的一年心想事成,万事如意。

源码地址如下

Github:https://github.com/WPFDevelopersOrg

Gitee:https://gitee.com/WPFDevelopersOrg

WPF开发者QQ群: 340500857 

Github:https://github.com/WPFDevelopersOrg

出处:https://www.cnblogs.com/yanjinhua

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载请著名作者 出处 https://github.com/WPFDevelopersOrg

技术群:添加小编微信并备注进群

小编微信:mm1552923   

公众号:dotNet编程大全    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值