在很早之前,就想過開發一款抽獎軟體,卻一直沒有實際去做,最近經過一段時間的準備,終於開發出了一款基於WPF+Sqlite版的抽獎軟體,包括客戶端和管理端。本項目主要是為了熟悉WPF開發流程,僅供學習分享使用,如有不足之處,還請指正。 ...
在很早之前,就想過開發一款抽獎軟體,卻一直沒有實際去做,最近經過一段時間的準備,終於開發出了一款基於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(禮品表),主要包括禮品名稱,圖片路徑等,如下所示:
CREATE TABLE gift (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name VARCHAR (255),
ImageUrl VARCHAR (255)
);
Lucky(獎品表),主要包括,獎品名稱,數量,對應禮品ID,獎品等級(如:一等獎,二等獎),獎品類型,獎品排序(抽獎順序),如下所示:
CREATE TABLE lucky (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name VARCHAR (50),
Count INTEGER,
GiftId INTEGER,
Level INTEGER,
LuckyType VARCHAR (50),
LuckyOrder INTEGER
);
User(抽獎用戶表),參與抽獎的用戶,主要用戶的名稱,如下所示:
CREATE TABLE user (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name VARCHAR (50)
);
Winner(中獎表),主要包括中獎用戶ID,獎品ID,中獎時間等。如下所示:
CREATE TABLE winner (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
userid INTEGER,
luckyid INTEGER,
winnertime DATETIME
);
功能設計
抽獎軟體主要包括客戶端,和管理端,主要功能如下:
- 客戶端,主要用於抽獎,包括首頁,抽獎頁面【Enter鍵開始和停止抽獎,Next鍵切換獎項】,結束語頁面。
- 管理端,主要用於管理數據信息,包括用戶管理,禮品管理,獎品管理,中獎管理等功能,主要是對各個數據表的增刪改查。
核心源碼
本實例項目雖然比較小,但作為一個完整的項目,為了層次清晰及便於維護,採用MVVM開發模式,UI和業務邏輯分層處理,並單獨封裝DAL層。
1. 抽獎頁面源碼
整個項目最核心的就是抽獎頁面,UI層代碼如下所示:
<UserControl x:Class="EasyLucky.Views.Lucky"
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:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:EasyLucky.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="1000">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}" PassEventArgsToCommand="True" ></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding MouseDownCommand}" PassEventArgsToCommand="True" ></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.ColumnSpan="2" Grid.RowSpan="3">
<Image Source="/imgs/BG_12.jpg" Stretch="Fill"></Image>
</Border>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="0 40 0 0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Center">
<TextBlock Text="正在抽取的是 " FontSize="40" Foreground="White" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding DataM.CurLucky.Lucky.Level}" FontSize="60" Foreground="Gold" FontWeight="DemiBold"></TextBlock>
<TextBlock Text=" 等獎,共 " FontSize="40" Foreground="White" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding DataM.CurLucky.Lucky.Count}" FontSize="60" Foreground="Gold" FontWeight="DemiBold"></TextBlock>
<TextBlock Text=" 名" FontSize="40" Foreground="White" VerticalAlignment="Center"></TextBlock>
</StackPanel>
<ItemsControl Grid.Row="1" Grid.Column="0" ItemsSource="{Binding DataM.CurUsers}" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<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}" >
</UniformGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="40" FontWeight="DemiBold" Foreground="White" Margin="30"></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Margin="100 0 0 10" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
<TextBlock Text="{Binding DataM.CurLucky.Lucky.Level}" FontSize="40" Foreground="Gold" FontWeight="DemiBold" VerticalAlignment="Center"></TextBlock>
<TextBlock Text=" 等獎獎品" FontSize="40" Foreground="White" VerticalAlignment="Center"></TextBlock>
</StackPanel>
<TextBlock Text="{Binding DataM.CurLucky.Gift.Name}" FontSize="40" Grid.Row="1" Grid.Column="0" Foreground="Gold" FontWeight="DemiBold" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<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>
</Grid>
</StackPanel>
<TextBlock x:Name="btn" Grid.Column="1" Grid.Row="2" Background="Transparent" Width="10" Height="10" Focusable="True" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<i:InvokeCommandAction Command="{Binding KeyDownCommand}" PassEventArgsToCommand="True"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</Grid>
</UserControl>
2. 業務邏輯源碼
業務邏輯代碼在ViewModel 中,如下所示:
開始抽獎,通過Enter鍵觸發:
private void Start()
{
cts = new CancellationTokenSource();
token = cts.Token;
task = Task.Run(() =>
{
var luckyCount = this.DataM.CurLucky.Lucky.Count;
var userCount = this.DataM.Users.Count;
var random = new Random(DateTime.Now.Second);
var rnd = random.Next(0,userCount);
int index = rnd;
if(index+luckyCount > userCount)
{
index = userCount - luckyCount;
}
while (!token.IsCancellationRequested)
{
var users=new List<User>();
if(index+luckyCount > userCount)
{
//讀到最後再迴圈讀取
for(int i = index; i < userCount; i++)
{
users.Add(this.DataM.Users[i]);
}
for(int i = 0; i < luckyCount - (userCount - index); i++)
{
users.Add(this.DataM.Users[i]);
}
index = luckyCount - (userCount - index);
}
else
{
//順序讀取
for (int i = index; i < index+luckyCount; i++)
{
users.Add(this.DataM.Users[i]);
}
index=index+luckyCount;
}
Application.Current.Dispatcher.Invoke(new Action(() =>
{
this.DataM.CurUsers = new ObservableCollection<User>(users);
}));
Thread.Sleep(100);
}
},token);
this.DataM.State = 1;
}
停止抽獎 ,並保存中獎結果:
private void Stop()
{
cts.Cancel();
//獲取當前獲獎名單
var users = this.DataM.CurUsers.ToList();
var lucky = this.DataM.CurLucky.Lucky;
if (winnerDal == null)
{
winnerDal = new WinnerDal();
}
foreach(var user in users)
{
var entity = new WinnerEntity()
{
UserId = user.Id,
LuckyId = lucky.Id,
WinnerTime = DateTime.Now,
};
int id= this.winnerDal.AddWinner(entity);
if(id <1)
{
MessageBox.Show("添加失敗");
break;
}
}
//
for(int i=0; i<users.Count; i++)
{
var user = users[i];
this.DataM.Users.Remove(user);//從列表中移除中獎名單
}
this.DataM.State=0;
}
下一個獎項,按照獎項順序選擇下一個獎項,通過Next鍵觸發,如下所示:
private void Next()
{
int order = this.DataM.CurLucky.Lucky.LuckyOrder;
var next = this.DataM.Luckys.FirstOrDefault(item => item.LuckyOrder > order);
if (next != null)
{
this.DataM.CurLucky.Lucky = next;
var giftId = this.DataM.CurLucky.Lucky.GiftId;
this.DataM.CurLucky.Gift = this.DataM.Gifts.FirstOrDefault(item => item.Id == giftId);
if (next.Count > 4)
{
this.DataM.Row = 2;
this.DataM.Column = (int)Math.Ceiling(next.Count * 1.0d / 2);
}
this.DataM.State = 0;
this.DataM.CurUsers.Clear();
}
else
{
WeakReferenceMessenger.Default.Send(new StateChangedMessage(2));
}
}
效果演示
抽獎軟體實例演示,客戶端主要包括首頁,抽獎頁,結束頁,如下所示:
首頁實例
抽獎頁面
結束語頁面
管理端主要是對數據的管理,包括禮品管理,用戶管理,獎項管理,中獎管理,屬於常規的數據管理頁面,如下所示:
源碼下載
1. gitee下載
源碼已上傳至gitee,用戶可通過gitee鏈接進行下載,如下所示:
項目鏈接:https://gitee.com/ahsiang/easy-lucky
2. 關鍵字下載
關註個人公眾號,回覆關鍵字Lucky即可,如下所示:
以上就是基於WPF+Sqlite開發抽獎軟體實例的全部內容,希望可以拋磚引玉,一起學習,共同進步。
作者:小六公子
出處:http://www.cnblogs.com/hsiang/
本文版權歸作者和博客園共有,寫文不易,支持原創,歡迎轉載【點贊】,轉載請保留此段聲明,且在文章頁面明顯位置給出原文連接,謝謝。
關註個人公眾號,定時同步更新技術及職場文章