用WPF设计一个简易的休息提醒闹钟

news2025/6/20 4:41:54

目录

    • 一.视频演示地址
    • 二.代码展示
    • 三.源代码:

最近利用工作之余,写了一个WPF程序玩玩,用来提醒自己在长时间学习后要休息一会儿哈哈,功能很简单,没啥难点

一.视频演示地址

可以设定间隔提醒时长和休息时长,点击开始之后会开始计时,当计时达到设定的间隔时常后,会进入休息页面会播放音乐,同时也会开始计时,当计时达到休息时长后,会关闭音乐并返回主页。

用WPF设计一个简易的休息提醒闹钟

二.代码展示

思路很简单,直接展示一些核心代码吧:

  1. 项目截图:

在这里插入图片描述

  1. App.xaml.cs代码,用于配置Prism框架一些服务以及初始化工作:
using AlarmWPF.ViewModels;
using AlarmWPF.Views;
using Prism.Ioc;
using System.Windows;

namespace AlarmWPF
{
	/// <summary>
	/// Interaction logic for App.xaml
	/// </summary>
	public partial class App
	{
		protected override Window CreateShell()
		{
			return Container.Resolve<MainWindow>();
		}

		protected override void RegisterTypes(IContainerRegistry containerRegistry)
		{
			containerRegistry.RegisterDialog<RestView,RestViewModel>();
		}
	}
}

  1. MainWindow.xaml代码
<Window x:Class="AlarmWPF.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        prism:ViewModelLocator.AutoWireViewModel="True"
        xmlns:hc="https://handyorg.github.io/handycontrol" ResizeMode="NoResize"
        Title="{Binding Title}" Height="350" Width="525" WindowStartupLocation="CenterScreen" Icon="/Images/alarmIcon.png" Unloaded="Window_Unloaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}"  VerticalAlignment="Center" Margin="16 0 0 0" Text="间隔多少分钟提醒:" FontSize="20" FontWeight="Bold"/>
            <hc:NumericUpDown Value="{Binding InternalMinutes}" HorizontalAlignment="Center"  VerticalAlignment="Center" Style="{StaticResource NumericUpDownBaseStyle}" Width="150" FontSize="20" FontWeight="Bold"/>
        </StackPanel>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}"  VerticalAlignment="Center" Margin="16 0 0 0" Text="休息多少分钟:" FontSize="20" FontWeight="Bold"/>
            <hc:NumericUpDown Value="{Binding RestMinutes}" HorizontalAlignment="Center"  VerticalAlignment="Center" Style="{StaticResource NumericUpDownBaseStyle}" Width="150" FontSize="20" FontWeight="Bold"/>
        </StackPanel>
        <Grid Grid.Row="3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Button Command="{Binding BtnStart}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"  IsEnabled="{Binding BtnStartEnable}" Grid.Column="0" Style="{StaticResource MaterialDesignFlatDarkBgButton}" Content="开始" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            <Button Command="{Binding BtnStop}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" IsEnabled="{Binding BtnStopEnable}"  Grid.Column="1" Style="{StaticResource MaterialDesignFlatDarkBgButton}" Content="停止" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
    </Grid>
</Window>


  1. MainWindowViewModel.cs代码:
using AlarmWPF.Views;
using HandyControl.Tools.Extension;
using Microsoft.Win32;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using Timer = System.Timers.Timer;

namespace AlarmWPF.ViewModels
{
	public class MainWindowViewModel : BindableBase
	{
		#region 属性
		private string _title = "自律闹钟";
		public string Title
		{
			get { return _title; }
			set { SetProperty(ref _title, value); }
		}

		private int internalMinutes;
		public int InternalMinutes
		{
			get { return internalMinutes; }
			set { SetProperty(ref internalMinutes, value); }
		}

		private int restMinutes;
		public int RestMinutes
		{
			get { return restMinutes; }
			set { SetProperty(ref restMinutes, value); }
		}


		private bool btnStartEnable=true;
		public bool BtnStartEnable
		{
			get { return btnStartEnable; }
			set { SetProperty(ref btnStartEnable, value); }
		}

		private bool btnStopEnable=true;
		public bool BtnStopEnable
		{
			get { return btnStopEnable; }
			set { SetProperty(ref btnStopEnable, value); }
		}

		public DelegateCommand<object> BtnStart { get; set; }
		public DelegateCommand<object> BtnStop { get; set; }
		private int endSeconds = 0;
		Timer timer;
		private IDialogService dialog;
		private Window window1;

		#endregion


		public MainWindowViewModel(IDialogService dialog)
		{
			window1 = new Window();
			this.dialog = dialog;
			BtnStart = new DelegateCommand<object>(Start);
			BtnStop = new DelegateCommand<object>(Stop);
			timer = new Timer(1000);
			timer.Enabled = false;
			timer.Elapsed += Timer_Elapsed;
		}

		private void Stop(object obj)
		{
		
			BtnStartEnable = true;
			BtnStopEnable = false;

			timer.Stop();
			timer.Enabled = false;
		}

		private void Start(object obj)
		{
			endSeconds = InternalMinutes * 60;
			BtnStartEnable = false;
			BtnStopEnable = true;


			timer.Enabled = true;
			timer.Start();
			window1 = obj as Window;
			window1.WindowStartupLocation = WindowStartupLocation.CenterScreen;
		}


		private void Timer_Elapsed(object sender, ElapsedEventArgs e)
		{
			endSeconds--;
			if (endSeconds==0)
			{
				timer.Stop();
				timer.Enabled=false;

				///parameters,添加向对话框传递的参数
				IDialogParameters parameters = new DialogParameters();
				parameters.Add("InternalMinutes", $"{InternalMinutes}");
				parameters.Add("RestMinutes", $"{RestMinutes}");

				Application.Current.Dispatcher.InvokeAsync(new Action(() =>
				{
					window1.Hide();
					dialog.ShowDialog("RestView",parameters,callback);
				}));
			}
		}

		/// <summary>
		/// 对话框关闭的时候调用此回调方法
		/// </summary>
		/// <param name="obj"></param>
		private void callback(IDialogResult obj)
		{
			window1.WindowStartupLocation = WindowStartupLocation.CenterScreen;
			window1.Show();
			BtnStartEnable = true;
			BtnStopEnable = false;
		}
	}
}

  1. RestView.xaml
<UserControl x:Class="AlarmWPF.Views.RestView"
             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:AlarmWPF.Views"
             xmlns:prism="http://prismlibrary.com/"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             prism:ViewModelLocator.AutoWireViewModel="True"
             xmlns:hc="https://handyorg.github.io/handycontrol"
             mc:Ignorable="d" 
             Background="White"
             d:DesignHeight="600" d:DesignWidth="800" >
    <prism:Dialog.WindowStyle>
        <Style TargetType="Window">
            <Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
            <Setter Property="ShowInTaskbar" Value="False"/>
            <Setter Property="WindowStyle" Value="None"/>
            <Setter Property="AllowsTransparency" Value="True"/>
        </Style>
    </prism:Dialog.WindowStyle>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="5*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Border Grid.Row="0">
            <Image Source="/Images/rest.jpg" Stretch="Fill" />
        </Border>
        <StackPanel Grid.Row="1">
            <TextBlock Text="{Binding RestText}" FontSize="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold"/>
        </StackPanel>
        <StackPanel  Grid.Row="2">
            <TextBlock Text="{Binding EndTimeText}" FontSize="15" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold"/>
        </StackPanel>
    </Grid>
</UserControl>

  1. RestViewModel.cs代码:
using HandyControl.Tools.Extension;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Media;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;

namespace AlarmWPF.ViewModels
{
	public class RestViewModel: BindableBase,IDialogAware
	{
		#region 属性

		public DelegateCommand CloseDialog { get;set; }
		public event Action<IDialogResult> RequestClose;

		private string restText="";
		public string RestText
		{
			get { return restText; }
			set { SetProperty(ref restText, value); }
		}
		private string endTimeText = "";
		public string EndTimeText
		{
			get { return endTimeText; }
			set { SetProperty(ref endTimeText, value); }
		}

		private int endTimeSeconds = 0;
		private  int totalTime=0;

		public string Title => "该休息了";
		private Timer timer;
		SoundPlayer player;

		#endregion

		public RestViewModel()
        {
			player=new SoundPlayer();
			timer = new Timer();
			timer.Enabled= false;
			timer.Interval = 1000;
			timer.Elapsed += Timer_Elapsed;
		}


		private void Timer_Elapsed(object sender, ElapsedEventArgs e)
		{
			if (endTimeSeconds==0)
			{
				timer.Enabled = false;
				timer.Stop();
				player.Stop();
				player.Dispose();
				Application.Current.Dispatcher.InvokeAsync(() =>
				{
					RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
				});
			}
			endTimeSeconds--;
			EndTimeText = $"{endTimeSeconds}秒后自动关闭";
		}

		public bool CanCloseDialog()
		{
			//允许关闭对话框
			return true;
		}

		public void OnDialogClosed()
		{
			//当对话框关闭的时候
			timer.Enabled = false;
			timer.Stop();
			player.Stop();
			player.Dispose();
		}

		public void OnDialogOpened(IDialogParameters parameters)
		{
			timer.Enabled = true;
			timer.Start();
			var internalMinutes = parameters.GetValue<string>("InternalMinutes");
			var restMinutes = parameters.GetValue<string>("RestMinutes");
			try
			{
				totalTime = int.Parse(restMinutes);
				endTimeSeconds = int.Parse(restMinutes)*60;
			}catch (Exception ex)
			{

			}
			RestText = $"亲,您又工作了{internalMinutes}分钟,该休息一下了!";
			EndTimeText = $"{endTimeSeconds}秒后自动关闭";

			string wavFile = @"music.wav";
			if (File.Exists(wavFile))
			{
				player.SoundLocation= wavFile;
				player.Load();
				player.Play();
				player.Dispose();
			}

		}
	}
}

三.源代码:

仓库链接

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】STL之stack、queue的使用和模拟实现+优先级队列(附仿函数)+容器适配器详解

之前的一段时间&#xff0c;我们共同学习了STL中一些容器&#xff0c;如string、vector和list等等。本章我们将步入新阶段的学习——容器适配器。本章将详解stack、queue的使用和模拟实现优先级队列&#xff08;附仿函数&#xff09;容器适配器等。 目录 &#xff08;一&…

WMI系列--关于WMI

本系列预计有三节,分别记录关于WMI的一些基础知识&#xff0c;WMI的永久订阅事件,WMI常见的攻防对抗手段 WMI简介 WMI 的全称是 Windows Management Instrumentation&#xff0c;即 Windows 管理规范&#xff0c;在 Windows 操作系统中&#xff0c;随着 WMI 技术的引入并在之…

Document Imaging SDK 11.6 for .NET Crack

Document Imaging SDK for .NET View, Convert, Annotate, Process,Edit, Scan, OCR, Print 基本上被认为是一种导出 PDF 解决方案&#xff0c;能够为用户和开发人员提供完整且创新的 PDF 文档处理属性。它具有提供简单集成的能力&#xff0c;可用于增强用户 .NET 的文档成像程…

c语言—指针进阶

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ…

HC小区管理系统-海康摄像头监控配置

HC小区管理系统-海康摄像头监控配置 【HC小区管理系统-海康摄像头监控配置】 HC小区管理系统-海康摄像头监控配置_哔哩哔哩_bilibili 监控配置说明&#xff1a; 一、安装HC物业系统 HC小区管理系统安装本地代码发布 二、安装物联网系统 三、安装srs 流媒体服务器 四、启动s…

MobTech MobLink|裂变拓新,助力运营

一、打破移动应用孤岛 在移动互联网时代&#xff0c;应用的数量和质量都在不断上升&#xff0c;用户的需求和体验也越来越高。然而&#xff0c;应用之间的跳转和互通却存在很多障碍和不便&#xff0c;导致用户的流失和挫败感。例如&#xff1a; 用户在浏览器或社交平台上看到一…

看完这个你就牛了,自动化测试框架设计

一、引言 随着IT技术的快速发展&#xff0c;软件开发变得越来越快速和复杂化。在这种背景下&#xff0c;传统的手工测试方式已经无法满足测试需求&#xff0c;而自动化测试随之而生。 自动化测试可以提高测试效率和测试质量&#xff0c;减少重复性的测试工作&#xff0c;从而…

前端大概要知道的 AST

认识 AST 定义&#xff1a;在计算机科学中&#xff0c;抽象语法树是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构&#xff0c;树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的&#xff0c;是因为这里的语法并不会表示出真实语法中…

手机测试—adb

一、Android Debug Bridge 1.1 Android系统主要的目录 1.2 ADB工具介绍 ADB的全称为Android Debug Bridge,就是起到调试桥的作用,是Android SDK里面一个多用途调试工具,通过它可以和Android设备或模拟器通信,借助adb工具,我们可以管理设备或手机模拟器的状态。还可以进行很多…

【负荷预测】基于VMD-SSA-LSTM光伏功率预测【可以换数据变为其他负荷等预测】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

文件小注意

目录 0 前言 1 标识 O_CREAT O_APPEND 2 ftruncate与truncate 3 O_DIRECT与O_DSYNC、O_SYNC 4 open与fopen 5 关于mmap 0 前言 文件操作在软件开发中是很常见的一件事。虽然与它相关的工作看起来不怎么起眼&#xff0c;无非就是通过通过open、read、write、close几个调用…

Unity——网格变形(制作一个压力球)

主要参考链接&#xff1a;Mesh Deformation, a Unity C# Tutorial&#xff08;本文为其翻译版&#xff09; unity项目下载链接&#xff1a;https://download.csdn.net/download/weixin_43042683/87679832 在物体上投射射线并画出调试线。将力转换为顶点的速度。用弹簧和阻尼保…

Rust社区引发舆论危机,问题到底出在哪儿?

围绕开源的法律问题&#xff0c;讨论焦点往往集中在开源许可证、软件著作权等方面&#xff0c;商标的讨论却极少引人关注。事实上&#xff0c;关于开源软件以及开源软件的衍生产品的商标使用情况往往处于某种灰色地带。 最近&#xff0c;Rust基金会正在就更新的商标政策征求反馈…

windows命令执行的几种绕过方法

windows命令执行的几种绕过方法介绍1、添加特殊符号2、定义变量3、切割字符串4、逻辑运算符在绕过中的作用5、利用for循环拼接命令介绍 反检测、反清理&#xff0c;是红队攻击中的重中之重&#xff0c;本文详细描述了几种windows执行命令的几种绕过手法。 1、添加特殊符号 w…

ERP软件的作用

ERP软件的运用是在企业管理系统的数据基础上实现的&#xff0c;它的应用涉及到企业的各个部门。ERP软件是在制造资源计划的基础上进一步发展而成的对企业供应链的管理软件。ERP是集采购、销售和库存、财务、生产管理和委托加工为一体的企业管理软件。它是集企业管理理念、业务流…

带你玩转Python爬虫(胆小者勿进)千万别做坏事·······

这节课很危险&#xff0c;哈哈哈哈&#xff0c;逗你们玩的 目录 写在前面 1 了解robots.txt 1.1 基础理解 1.2 使用robots.txt 2 Cookie 2.1 两种cookie处理方式 3 常用爬虫方法 3.1 bs4 3.1.1 基础介绍 3.1.2 bs4使用 3.1.2 使用例子 3.2 xpath 3.2.1 xpath基础介…

【计算机图形学】扫描转换算法(Bresenham1/4圆法 椭圆两头逼近法 方形刷子)

一 实验目的 编写弧线的光栅扫描转换算法&#xff0c;并对线宽与线形的算法加以探讨熟悉圆和椭圆画线的算法二 实验算法理论分析Bresenham法&#xff08;1/4圆&#xff09;&#xff1a; 椭圆扫描转换——两头逼近法&#xff1a; 处理线宽问题&#xff1a; 方形刷子宽度存在的…

JS内置对象1

JS中的对象分为&#xff1a;自定义对象、内置对象、浏览器对象内置对象&#xff1a;JS语言自带的一些对象&#xff0c;已经提高最基本的功能常见内置对象&#xff1a;Math、Date、Array、String学习内置对象可通过查阅文档&#xff0c;即MDN/W3C来查阅 …

3.1 微分中值定理

思维导图&#xff1a; 学习目标&#xff1a; 我会按照以下步骤来学习微分中值定理&#xff1a; 理解导数的定义和性质&#xff1a;在学习微分中值定理之前&#xff0c;首先要对导数的定义和性质有一个清晰的理解&#xff0c;包括导数的几何意义和导数存在的条件等。学习拉格朗…

作为大学生,你还不会搭建chatGPT微应用吗?

目录 引言ChatGPT是什么&#xff1f;背景&#xff1a;ChatGPT敢为人先&#xff0c;打破全球僵局示例演示&#xff1a;基于ChatGPT微应用实现的条件及步骤&#xff08;1&#xff09;整体框架&#xff08;2&#xff09;搭建前的准备工作&#xff08;3&#xff09;实际搭建步骤&a…