翼度科技»论坛 编程开发 .net 查看内容

基于WPF+Sqlite开发抽奖软件【内附源码】

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
在很早之前,就想过开发一款抽奖软件,却一直没有实际去做,最近经过一段时间的准备,终于开发出了一款基于WPF+Sqlite版的抽奖软件,包括客户端和管理端。本项目主要是为了熟悉WPF开发流程,仅供学习分享使用,如有不足之处,还请指正。
 
涉及知识点

 
抽奖软件是包括客户端和管理端,在抽奖软件开发过程中,主要用到了如下知识点:

  • 开发工具:Visual Studion 2022
  • 开发框架:.NET6.0 + WPF
  • MVVM框架:CommunityToolkit.Mvvm 8.2.2
  • 数据库:Sqlite
  • ORM框架:SqlSugarCore 5.1.4.154
  • 数据库客户端:SQLiteStudio 3.4.4
 
数据表设计

 
根据抽奖软件的功能进行拆解,主要包括:Gift(礼品表),Lucky(奖品表),User(抽奖用户表),Winner(中奖表),各个表详细创建语句如下所示:
Gift(礼品表),主要包括礼品名称,图片路径等,如下所示:
  1. CREATE TABLE gift (
  2.     Id       INTEGER       PRIMARY KEY AUTOINCREMENT,
  3.     Name     VARCHAR (255),
  4.     ImageUrl VARCHAR (255)
  5. );
复制代码
Lucky(奖品表),主要包括,奖品名称,数量,对应礼品ID,奖品等级(如:一等奖,二等奖),奖品类型,奖品排序(抽奖顺序),如下所示:
  1. CREATE TABLE lucky (
  2.     Id         INTEGER      PRIMARY KEY AUTOINCREMENT,
  3.     Name       VARCHAR (50),
  4.     Count      INTEGER,
  5.     GiftId     INTEGER,
  6.     Level      INTEGER,
  7.     LuckyType  VARCHAR (50),
  8.     LuckyOrder INTEGER
  9. );
复制代码
 User(抽奖用户表),参与抽奖的用户,主要用户的名称,如下所示:
  1. CREATE TABLE user (
  2.     Id   INTEGER      PRIMARY KEY AUTOINCREMENT,
  3.     Name VARCHAR (50)
  4. );
复制代码
 Winner(中奖表),主要包括中奖用户ID,奖品ID,中奖时间等。如下所示:
  1. CREATE TABLE winner (
  2.     Id         INTEGER  PRIMARY KEY AUTOINCREMENT,
  3.     userid     INTEGER,
  4.     luckyid    INTEGER,
  5.     winnertime DATETIME
  6. );
复制代码
 
功能设计

 
抽奖软件主要包括客户端,和管理端,主要功能如下:

  • 客户端,主要用于抽奖,包括首页,抽奖页面【Enter键开始和停止抽奖,Next键切换奖项】,结束语页面。
  • 管理端,主要用于管理数据信息,包括用户管理,礼品管理,奖品管理,中奖管理等功能,主要是对各个数据表的增删改查。
 
核心源码

 
本实例项目虽然比较小,但作为一个完整的项目,为了层次清晰及便于维护,采用MVVM开发模式,UI和业务逻辑分层处理,并单独封装DAL层。
 
1. 抽奖页面源码

 
整个项目最核心的就是抽奖页面,UI层代码如下所示:
  1. <UserControl x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6.              xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
  7.              xmlns:local="clr-namespace:EasyLucky.Views"
  8.              mc:Ignorable="d"
  9.              d:DesignHeight="450" d:DesignWidth="1000">
  10.     <i:Interaction.Triggers>
  11.         <i:EventTrigger EventName="Loaded">
  12.             <i:InvokeCommandAction Command="{Binding LoadedCommand}" PassEventArgsToCommand="True" ></i:InvokeCommandAction>
  13.         </i:EventTrigger>
  14.     </i:Interaction.Triggers>
  15.     <Grid>
  16.         <i:Interaction.Triggers>
  17.             <i:EventTrigger EventName="MouseDown">
  18.                 <i:InvokeCommandAction Command="{Binding MouseDownCommand}" PassEventArgsToCommand="True" ></i:InvokeCommandAction>
  19.             </i:EventTrigger>
  20.         </i:Interaction.Triggers>
  21.         <Grid.ColumnDefinitions>
  22.             <ColumnDefinition></ColumnDefinition>
  23.             <ColumnDefinition></ColumnDefinition>
  24.         </Grid.ColumnDefinitions>
  25.         <Grid.RowDefinitions>
  26.             <RowDefinition Height="Auto"></RowDefinition>
  27.             <RowDefinition Height="*"></RowDefinition>
  28.             <RowDefinition Height="Auto"></RowDefinition>
  29.         </Grid.RowDefinitions>
  30.         <Border Grid.ColumnSpan="2" Grid.RowSpan="3">
  31.             <Image Source="/imgs/BG_12.jpg"  Stretch="Fill"></Image>
  32.         </Border>
  33.         <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="0 40 0 0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Center">
  34.             <TextBlock Text="正在抽取的是 " FontSize="40" Foreground="White" VerticalAlignment="Center"></TextBlock>
  35.             <TextBlock Text="{Binding DataM.CurLucky.Lucky.Level}" FontSize="60" Foreground="Gold" FontWeight="DemiBold"></TextBlock>
  36.             <TextBlock Text=" 等奖,共 " FontSize="40" Foreground="White" VerticalAlignment="Center"></TextBlock>
  37.             <TextBlock Text="{Binding DataM.CurLucky.Lucky.Count}" FontSize="60" Foreground="Gold" FontWeight="DemiBold"></TextBlock>
  38.             <TextBlock Text=" 名" FontSize="40" Foreground="White" VerticalAlignment="Center"></TextBlock>
  39.         </StackPanel>
  40.         <ItemsControl Grid.Row="1" Grid.Column="0" ItemsSource="{Binding DataM.CurUsers}" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center">
  41.             <ItemsControl.ItemsPanel>
  42.                 <ItemsPanelTemplate>
  43.                     <UniformGrid Columns="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.DataM.Column}" Rows="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.DataM.Row}" >
  44.                     </UniformGrid>
  45.                 </ItemsPanelTemplate>
  46.             </ItemsControl.ItemsPanel>
  47.             <ItemsControl.ItemTemplate>
  48.                 <DataTemplate>
  49.                     <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="40" FontWeight="DemiBold" Foreground="White" Margin="30"></TextBlock>
  50.                 </DataTemplate>
  51.             </ItemsControl.ItemTemplate>
  52.         </ItemsControl>
  53.         
  54.         <StackPanel Margin="100 0 0 10" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center">
  55.             <Grid>
  56.                 <Grid.ColumnDefinitions>
  57.                     <ColumnDefinition></ColumnDefinition>
  58.                     <ColumnDefinition></ColumnDefinition>
  59.                 </Grid.ColumnDefinitions>
  60.                 <Grid.RowDefinitions>
  61.                     <RowDefinition></RowDefinition>
  62.                     <RowDefinition></RowDefinition>
  63.                 </Grid.RowDefinitions>
  64.                 <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
  65.                     <TextBlock Text="{Binding DataM.CurLucky.Lucky.Level}" FontSize="40" Foreground="Gold" FontWeight="DemiBold" VerticalAlignment="Center"></TextBlock>
  66.                     <TextBlock Text=" 等奖奖品" FontSize="40" Foreground="White" VerticalAlignment="Center"></TextBlock>
  67.                 </StackPanel>
  68.                 <TextBlock Text="{Binding DataM.CurLucky.Gift.Name}" FontSize="40" Grid.Row="1" Grid.Column="0" Foreground="Gold" FontWeight="DemiBold" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
  69.                 <Image Margin="20 0 0 0" Source="{Binding DataM.CurLucky.Gift.ImageSource}" Stretch="Fill" Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Width="200" Height="150"></Image>
  70.             </Grid>
  71.         </StackPanel>
  72.         <TextBlock x:Name="btn" Grid.Column="1" Grid.Row="2" Background="Transparent" Width="10" Height="10" Focusable="True" HorizontalAlignment="Right" VerticalAlignment="Bottom">
  73.             <i:Interaction.Triggers>
  74.                 <i:EventTrigger EventName="KeyDown">
  75.                     <i:InvokeCommandAction Command="{Binding KeyDownCommand}" PassEventArgsToCommand="True"></i:InvokeCommandAction>
  76.                 </i:EventTrigger>
  77.             </i:Interaction.Triggers>
  78.         </TextBlock>
  79.     </Grid>
  80. </UserControl>
复制代码
 
2. 业务逻辑源码

 
业务逻辑代码在ViewModel 中,如下所示:
 
开始抽奖,通过Enter键触发:
  1. private void Start()
  2. {
  3.         cts = new CancellationTokenSource();
  4.         token = cts.Token;
  5.         task = Task.Run(() =>
  6.         {
  7.                 var luckyCount = this.DataM.CurLucky.Lucky.Count;
  8.                 var userCount = this.DataM.Users.Count;
  9.                 var random = new Random(DateTime.Now.Second);
  10.                 var rnd = random.Next(0,userCount);
  11.                 int index = rnd;
  12.                 if(index+luckyCount > userCount)
  13.                 {
  14.                         index = userCount - luckyCount;
  15.                 }
  16.                
  17.                 while (!token.IsCancellationRequested)
  18.                 {
  19.                         var users=new List<User>();
  20.                         if(index+luckyCount > userCount)
  21.                         {
  22.                                 //读到最后再循环读取
  23.                                 for(int i = index; i < userCount; i++)
  24.                                 {
  25.                                         users.Add(this.DataM.Users[i]);
  26.                                 }
  27.                                 for(int i = 0; i < luckyCount - (userCount - index); i++)
  28.                                 {
  29.                                         users.Add(this.DataM.Users[i]);
  30.                                 }
  31.                                 index = luckyCount - (userCount - index);
  32.                         }
  33.                         else
  34.                         {
  35.                                 //顺序读取
  36.                                 for (int i = index; i < index+luckyCount; i++)
  37.                                 {
  38.                                         users.Add(this.DataM.Users[i]);
  39.                                 }
  40.                                 index=index+luckyCount;
  41.                         }
  42.                         Application.Current.Dispatcher.Invoke(new Action(() =>
  43.                         {
  44.                                 this.DataM.CurUsers = new ObservableCollection<User>(users);
  45.                         }));
  46.                         Thread.Sleep(100);
  47.                 }
  48.         },token);
  49.         this.DataM.State = 1;
  50. }
复制代码
 
停止抽奖 ,并保存中奖结果:
  1. private void Stop()
  2. {
  3.         cts.Cancel();
  4.         //获取当前获奖名单
  5.         var users = this.DataM.CurUsers.ToList();
  6.         var lucky = this.DataM.CurLucky.Lucky;
  7.         if (winnerDal == null)
  8.         {
  9.                 winnerDal = new WinnerDal();
  10.         }
  11.         foreach(var user in users)
  12.         {
  13.                 var entity = new WinnerEntity()
  14.                 {
  15.                         UserId = user.Id,
  16.                         LuckyId = lucky.Id,
  17.                         WinnerTime = DateTime.Now,
  18.                 };
  19.                 int id= this.winnerDal.AddWinner(entity);
  20.                 if(id <1)
  21.                 {
  22.                         MessageBox.Show("添加失败");
  23.                         break;
  24.                 }
  25.         }
  26.         //
  27.         for(int i=0; i<users.Count; i++)
  28.         {
  29.                 var user = users[i];
  30.                 this.DataM.Users.Remove(user);//从列表中移除中奖名单
  31.         }
  32.         this.DataM.State=0;
  33. }
复制代码
 
效果演示

 
抽奖软件实例演示,客户端主要包括首页,抽奖页,结束页,如下所示:
 
首页实例

 
抽奖页面

 
结束语页面

 
管理端主要是对数据的管理,包括礼品管理,用户管理,奖项管理,中奖管理,属于常规的数据管理页面,如下所示:

 
源码下载

 
1. gitee下载

 
源码已上传至gitee,用户可通过gitee链接进行下载,如下所示:
项目链接:https://gitee.com/ahsiang/easy-lucky

 
2. 关键字下载

 
关注个人公众号,回复关键字Lucky即可,如下所示:

以上就是基于WPF+Sqlite开发抽奖软件实例的全部内容,希望可以抛砖引玉,一起学习,共同进步。

来源:https://www.cnblogs.com/hsiang/p/18205190
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具