C# WPF上位机开发(抽奖程序)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        每到年末或者是尾牙的时候,很多公司都会办一些年终的清楚活动,感谢员工过去一年辛苦的付出。这个时候,作为年会的重头戏,那就是抽奖环节了。抽奖一般来说,有很多的方法。比如说,可以是物理抽奖的方法,即每一个人写一个抽奖券,放在统一的盒子里面;也可以是电子的方法,这就是今天说的抽奖程序。

        前面既然我们已经学习了c# wpf,那么完全可以自己做一个抽奖程序出来。在做之前,我们可以假定抽奖的数字有几位,有几个按钮,显示效果怎么样。这部分不要怕麻烦,可以自己设计一个效果图出来。

1、设计界面

        界面部分的设计可以简单一点,比如说只需要显示三个label和两个按钮。三个label,也就是快速跳动的数字。而两个按钮则分别是开始按钮、结束按钮。开始按钮按下去的时候,数字开始跳动;等到结束按钮被按下去的时候,那么屏幕上留下来的数字就是我们需要的抽奖数字。当然,目前为止,这里显示的数字只有三个,如果公司规模比较大,现实的数字可以根据需求添加几位也是可以的。设计完毕之后,它的代码是这样的,

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="Lottery" Height="450" Width="800">
    <Grid>
        
        <Label x:Name="num1" Content="0" Foreground="Blue"  FontSize="80" HorizontalAlignment="Left" Margin="297,103,0,0" VerticalAlignment="Top"/>
        <Label x:Name="num2" Content="0" Foreground="Blue" FontSize="80" HorizontalAlignment="Left" Margin="362,103,0,0" VerticalAlignment="Top"/>
        <Label x:Name="num3" Content="0" Foreground="Blue" FontSize="80" HorizontalAlignment="Left" Margin="432,103,0,0" VerticalAlignment="Top"/>
        <Button x:Name="start"  Content="Start" Foreground="Green" Click="Start_Click" HorizontalAlignment="Left" Margin="263,270,0,0" VerticalAlignment="Top" Width="95" Height="45">
            <Button.Resources>
                <Style TargetType="{x:Type Border}">
                    <Setter Property="CornerRadius" Value="5"></Setter>
                </Style>
            </Button.Resources>
        </Button>
        <Button x:Name="stop" Content="Stop" Foreground="Green" Click="Stop_Click" HorizontalAlignment="Left" Margin="415,270,0,0" VerticalAlignment="Top" Width="95" Height="45">
            <Button.Resources>
                <Style TargetType="{x:Type Border}">
                    <Setter Property="CornerRadius" Value="5"></Setter>
                </Style>
            </Button.Resources>
        </Button>
    </Grid>
</Window>

 

2、实际的设计效果

       一般写完xaml之后,对于效果还需要进行微调处理。比如字体大小,字体位置,按钮的大小,按钮的位置,按钮的颜色,看一下效果,

3、代码编写

        实现了界面之后,下面要做的就是界面代码编写。之前我们编写了倒计时软件,它的做法就是每周期减去1。抽奖程序的代码其实很类似。首先我们需要定时生成一个随机数。当然为了体现公平性,这个生成的周期要快一点,不再是1s更新一次,而是几十ms更新一次。随机数的生成,不需要自己考虑随机算法,而是直接使用c#自带的sdk即可。接着,有了这个随机数之后,下面就是把相关的数据显示到界面之上,这和之前的倒计时软件是一样的。最后就是丰富start和stop按钮的编写,start按钮代表开始随机数的生成,而stop按钮则表示结束随机数的生成。因为抽奖是需要不停迭代进行的,所以两个按钮基本上是一个互斥的关系。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private int flag = 0;
        private System.Windows.Threading.DispatcherTimer dispatcherTimer = null;
        private int num = 0;

        // construct function
        public MainWindow()
        {
            InitializeComponent();

            stop.IsEnabled = false;
        }

        // start button function
        private void Start_Click(object sender, RoutedEventArgs e)
        {
            dispatcherTimer = null;
            dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
            dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 20);
            dispatcherTimer.Start();

            start.IsEnabled = false;
            stop.IsEnabled = true;
            flag = 1;
        }

        // timer function
        private void dispatcherTimer_Tick(object sender, EventArgs e)//计时执行的程序
        {
            Random Ran = new Random();
            num = Ran.Next(1,999);

            if (flag == 0)
            {
                dispatcherTimer.Stop();
                return;
            }

            display_number();
        }

        private void display_number()
        {
            // display num
            num1.Content = Convert.ToString(num / 100);
            num2.Content = Convert.ToString((num % 100) /10);
            num3.Content = Convert.ToString(num % 10);
        }

        // stop button function
        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            flag = 0;
            start.IsEnabled = true;
            stop.IsEnabled = false;
        }
    }
}

        如上面代码所示,整个逻辑当中比较重要的内容就是两部分,分别是Start_Click和Stop_Click。前者创建一个定时器,每20ms调用一下回调函数。在dispatcherTimer_Tick函数中,利用Random生成一个随机数,再利用display_number显示出来。当然,如果发现flag==0,则代表定时器已经停止。后者Stop_Click则比较简单,主要就是flag置位。

4、测试运行

        测试相对而言就比较简单,单击运行即可。观察一下Start按下去的时候,数字有没有发生跳动;Stop按下去的时候,数字跳动有没有停止。如果一切ok,那代表软件是编写成功的。

        另外细心的同学发现了,整个软件编写过程中有一个bug,那就是已经中奖的同学还有可能再次中奖。所以这部分代码大家可以考虑下如何才能编写,才能保证这个错误不再发生。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/204670.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

继承中的析构函数的权限的深入了解

如果一个父类中的析构函数如果设置为 private 权限 &#xff0c;一个子类public继承了这个父类&#xff0c;那么 这个父类可以创建对象吗&#xff1f; 答案是 不可以 看看下面的代码 class A { public:private:~A() {} };class B :public A {A a; // 这个地方编译不报错&…

8.0 新特性 - Generated Invisible Primary Key

文章目录 说明1. GIPK 介绍1.1 参数设置2.2 可见性测试2.3 修改元数据可见性2.4 修改查询可见性 2. GIPK 测试2.1 Binlog 分析2.2 主从复制2.3 逻辑备份2.4 其它限制2.4.1 AUTO_INCREMENT 属性2.4.2 my_row_id 关键字 后记 说明 MySQL Innodb 引擎采用的是 IOT&#xff08;索引…

ESP32单片机案例

工具&#xff1a;VScode PlatformIO IDE 注&#xff1a;B站视频学习笔记。 1、继电器 1&#xff09;硬件电路 2&#xff09;程序 #include <Arduino.h> #define RELAY_PIN 15//初始化定时器 hw_timer_t *timer NULL;void timer_interrupt(){digitalWrite(RELAY_PIN…

低价商品采购API接口

采购商品地址http://sly.yizhaosulianyun.com/More/Push/888889?type3 低价商品采购API接口 1) 请求地址 http://sly.yizhaosulianyun.com/jd/keyWords 2) 调用方式&#xff1a;HTTP post 3) 接口描述&#xff1a; 低价商品采购接口 4) 请求参数: POST参数: 字段名称字段…

图论——最小割问题

Capacity&#xff08;S&#xff0c;T) Min-Cut(通俗的说就是用最小的力气隔断&#xff09; 最小割并不唯一 最大流最小割定理 对于一个网络流问题&#xff0c;最大流的流量最小割的容量 寻找最小割 可以使用Edmonds-karp or Dinic algorithm 首先寻找任意一个最大流&#xff…

一文讲透Python机器学习特征选择之互信息法

1.互信息法的基本思想 互信息&#xff08;Mutual Information&#xff0c;MI&#xff09;的基本思想是计算每个特征变量与目标变量之间的互信息统计量&#xff0c;互信息统计量衡量变量之间的依赖关系。两个随机变量之间的互信息统计量肯定是非负值&#xff0c;当且仅当两个随…

Java将JavaFX程序最小化托盘

Windows最小化拖盘其实就是将程序放到托盘里面,需要的时候再点击托盘里面的应用图标,此时就可以正常使用应用了,托盘如下: 下面是一个简单的Java程序,可以把窗口最小化到系统托盘: import java.awt.*; import java.awt.event.*; import javax.swing.*;public class Tray…

【算法每日一练]-图论(保姆级教程篇9 最小生成树 ,并查集篇)#道路修建 #兽径管理

目录 题目&#xff1a;道路修建 思路&#xff1a; 题目&#xff1a;兽径管理 思路&#xff1a; 题目&#xff1a;道路修建 思路&#xff1a; “让这些点全部连在一起的最小代价”很明显是最小生成树。绝对不能kruskal&#xff0c;存边一定会超内存。所以只能prim。 但是…

滚珠丝杆在各种自动化设备中的作用

滚珠丝杆因其具有高精度、高刚度和长寿命等特性&#xff0c;成为许多设备中的重要组成部分&#xff0c;在许多行业中都有广泛的应用&#xff0c;接下来我们看看滚珠丝杆的具体应用有哪些&#xff1f; 1、打孔机&#xff1a;提供精确的导向&#xff0c;使打孔机的滑块能够沿固定…

拥抱未来:大语言模型解锁平台工程的无限可能

01 了解大型语言模型 (LLM) 大型语言模型&#xff08;LLM&#xff09;是一种人工智能&#xff08;AI&#xff09;算法&#xff0c;它使用深度学习技术和海量数据集来理解、总结、生成和预测新内容。凭借合成大量信息的能力&#xff0c;LLM 可以提高以前需要人类专家的业务流程的…

todesk连接ubuntu显示当前系统并无桌面环境,或无显示器,无法显示远程桌面,您需要自行安装X11桌面环境,或者使用终端文件功能

ToDesk远程遇到的问题如上图&#xff0c;换向日葵直接黑屏&#xff1b; 问题原因 截止发文时间&#xff0c;Todesk只支持X11协议&#xff0c;没有适配最新的Wayland协议&#xff0c;所以我们需要把窗口系统调整为X11才可以。 解决方法 修改配置文件&#xff0c;关闭wayland su…

精密制造ERP系统包含哪些模块?精密制造ERP软件是做什么的

不同种类的精密制造成品有区别化的制造工序、工艺流转、品质标准、生产成本、营销策略等&#xff0c;而多工厂、多仓库、多车间、多部门协同问题却是不少精密制造企业遇到的管理难题。 有些产品结构较为复杂&#xff0c;制造工序繁多&#xff0c;关联业务多&#xff0c;传统的…

Python (十六) 错误和异常

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

Windows10设置定时提醒

文章目录 Windows10设置定时提醒创建提醒文件新建文本文档修改文件编码和后缀双击测试 创建文件夹创建任务测试运行 Windows10设置定时提醒 创建提醒文件 新建文本文档 修改文件编码和后缀 双击测试 创建文件夹 创建任务 创建触发器 选择程序 测试运行 弹窗正常

轻盈未来:气膜建筑的绿色时尚

随着可持续发展理念的日益深入人心&#xff0c;建筑行业也在不断追求绿色、环保的设计与施工方案。气膜建筑&#xff0c;作为一种创新而轻盈的设计理念&#xff0c;正在走在绿色时尚的前沿。本文将探讨气膜建筑的独特之处以及其如何与环保理念相结合&#xff0c;领航着未来建筑…

如何使用Qchan搭建更好保护个人隐私的本地图床并在公网可访问

文章目录 前言1. Qchan网站搭建1.1 Qchan下载和安装1.2 Qchan网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar云端设置2.2 Cpolar本地设置 3. 公网访问测试总结 前言 图床作为云存储的一项重要应用场景&#xff0c;在大量开发人员的努力下&#xff0c;已经开发出大…

堆栈_栈实现队列

//请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; // // 实现 MyQueue 类&#xff1a; // // // void push(int x) 将元素 x 推到队列的末尾 // int pop() 从队列的开头移除并返回元素…

Redis多机数据库

文章目录 Redis多机数据库一、主从复制1、旧版复制功能的实现a、同步b、命令传播 2、旧版复制功能的缺陷3、新版复制功能的实现a、部分同步功能b、复制实现步骤 4、心跳检测 二、哨兵1、Sentinel概念2、Sentinel初始化流程3、故障转移过程 三、集群1、几个概念2、集群创建流程a…

C++ day43 最后一块石头的重量 目标和 一和零

题目1&#xff1a;1049 最后一块石头的重量 题目链接&#xff1a;最后一块石头的重量 对题目的理解 整数数组stone[i]表示第i块石头的重量&#xff0c;每次从中选出任意两块石头(x<y)粉碎 如果两块石头重量相等&#xff0c;就会被完全粉碎&#xff1b;如果不等&#xff…

Docker Swarm总结+Jenkins安装配置与集成snarqube和目标服务器(4/5)

博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码下载地址&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb;…