分享如何使用WPF 制作 Windows 屏保
WPF 制作 Windows 屏保
作者:驚鏵
原文链接:https://github.com/yanjinhuagood/ScreenSaver
框架使用
.NET452
;Visual Studio 2019
;项目使用 MIT 开源许可协议;
更多效果可以通过GitHub[1]|码云[2]下载代码;
也可以自行添加天气信息等。
正文
屏保程序的本质上就是一个
Win32
窗口应用程序;把编译好一个窗口应用程序之后,把扩展名更改为
scr
,于是你的屏幕保护程序就做好了;选中修改好的
scr
程序上点击右键,可以看到一个安装
选项,点击之后就安装了;安装之后会立即看到我们的屏幕保护程序已经运行起来了;
处理屏幕保护程序参数如下
/s 屏幕保护程序开始,或者用户点击了
预览
按钮;/c 用户点击了
设置
按钮;/p 用户选中屏保程序之后,在预览窗格中显示;
1)MainWindow.xaml
代码如下;
<Window x:Class="ScreenSaver.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:system="clr-namespace:System;assembly=mscorlib"xmlns:drawing="http://www.microsoft.net/drawing"xmlns:local="clr-namespace:ScreenSaver"mc:Ignorable="d" WindowStyle="None"Title="MainWindow" Height="450" Width="800"><Grid x:Name="MainGrid"><drawing:PanningItems ItemsSource="{Binding stringCollection,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"x:Name="MyPanningItems"><drawing:PanningItems.ItemTemplate><DataTemplate><Rectangle><Rectangle.Fill><ImageBrush ImageSource="{Binding .}"/></Rectangle.Fill></Rectangle></DataTemplate></drawing:PanningItems.ItemTemplate></drawing:PanningItems><Grid HorizontalAlignment="Center" VerticalAlignment="Top"Margin="0,50,0,0"><Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions><Grid.Resources><Style TargetType="TextBlock"><Setter Property="FontSize" Value="90"/><Setter Property="FontWeight" Value="Black"/><Setter Property="Foreground" Value="White"/></Style></Grid.Resources><WrapPanel><TextBlock Text="{Binding Hour,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"/><TextBlock Text=":" x:Name="PART_TextBlock"><TextBlock.Triggers><EventTrigger RoutedEvent="FrameworkElement.Loaded"><BeginStoryboard><Storyboard><DoubleAnimation Duration="00:00:01"From="1"To="0"Storyboard.TargetName="PART_TextBlock"Storyboard.TargetProperty="Opacity"RepeatBehavior="Forever"FillBehavior="Stop"/></Storyboard></BeginStoryboard></EventTrigger></TextBlock.Triggers></TextBlock><TextBlock Text="{Binding Minute,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"/></WrapPanel><TextBlock Grid.Row="1" FontSize="45" HorizontalAlignment="Center" Text="{Binding Date,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"/></Grid></Grid>
</Window>
2) MainWindow.xaml.cs
代码如下;
当屏保启动后需要注意如下
将鼠标设置为不可见
Cursors.None
;将窗体设置为最大化
WindowState.Maximized
;WindowStyle
设置为"None"
;注意监听
鼠标按下
和键盘按键
则退出屏保;
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;namespace ScreenSaver
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public static readonly DependencyProperty stringCollectionProperty =DependencyProperty.Register("stringCollection", typeof(ObservableCollection<string>), typeof(MainWindow),new PropertyMetadata(null));public static readonly DependencyProperty HourProperty =DependencyProperty.Register("Hour", typeof(string), typeof(MainWindow), new PropertyMetadata(null));public static readonly DependencyProperty MinuteProperty =DependencyProperty.Register("Minute", typeof(string), typeof(MainWindow), new PropertyMetadata(null));public static readonly DependencyProperty SecondProperty =DependencyProperty.Register("Second", typeof(string), typeof(MainWindow), new PropertyMetadata(null));public static readonly DependencyProperty DateProperty =DependencyProperty.Register("Date", typeof(string), typeof(MainWindow), new PropertyMetadata());private readonly DispatcherTimer timer = new DispatcherTimer();public MainWindow(){InitializeComponent();Loaded += delegate{WindowState = WindowState.Maximized;Mouse.OverrideCursor = Cursors.None;var date = DateTime.Now;Hour = date.ToString("HH");Minute = date.ToString("mm");Date =$"{date.Month} / {date.Day} {CultureInfo.CurrentCulture.DateTimeFormat.GetDayName(date.DayOfWeek)}";stringCollection = new ObservableCollection<string>();var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images");var directoryInfo = new DirectoryInfo(path);foreach (var item in directoryInfo.GetFiles()){if (Path.GetExtension(item.Name) != ".jpg") continue;stringCollection.Add(item.FullName);}timer.Interval = TimeSpan.FromSeconds(1);timer.Tick += delegate{date = DateTime.Now;Hour = date.ToString("HH");Minute = date.ToString("mm");Date =$"{date.Month} / {date.Day} {CultureInfo.CurrentCulture.DateTimeFormat.GetDayName(date.DayOfWeek)}";};timer.Start();};MouseDown += delegate { Application.Current.Shutdown(); };KeyDown += delegate { Application.Current.Shutdown(); };}public ObservableCollection<string> stringCollection{get => (ObservableCollection<string>)GetValue(stringCollectionProperty);set => SetValue(stringCollectionProperty, value);}public string Hour{get => (string)GetValue(HourProperty);set => SetValue(HourProperty, value);}public string Minute{get => (string)GetValue(MinuteProperty);set => SetValue(MinuteProperty, value);}public string Second{get => (string)GetValue(SecondProperty);set => SetValue(SecondProperty, value);}public string Date{get => (string)GetValue(DateProperty);set => SetValue(DateProperty, value);}}
}
参考①[3]参考②[4]
参考资料
[1]
GitHub: https://github.com/yanjinhuagood/ScreenSaver
[2]码云: https://gitee.com/yanjinhua/ScreenSaver
[3]参考①: https://blog.walterlv.com/post/write-a-windows-screen-saver-using-wpf.html
[4]参考②: https://wbsimms.com/create-screensaver-net-wpf/