基於WPF+Sqlite開發抽獎軟件【內附源碼】

在很早之前,就想過開發一款抽獎軟件,卻一直沒有實際去做,最近經過一段時間的準備,終於開發出了一款基於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開發抽獎軟件實例的全部內容,希望可以拋磚引玉,一起學習,共同進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章