【炫丽】从0开始做一个WPF+Blazor对话小程序( 四 )

下面给出代码简单说明:

  1. 第一个div充做窗体的标题栏区域,注册了双击事件调用窗体最大化(还原)方法、鼠标按下与释放调用窗体的移动开始与结束方法;
  2. 在第一个div里,其中有3个按钮,即窗体的控制按钮,调用窗体最小化、最大化(还原)、关闭方法调用;
  3. 另有两个按钮 , 演示单击调用JavaScriptalert方法弹出消息 。

【炫丽】从0开始做一个WPF+Blazor对话小程序

文章插图
运行效果如下:
【炫丽】从0开始做一个WPF+Blazor对话小程序

文章插图
实现这个效果,还有一些代码:
  1. 上面的代码调用了一些方法实现窗体操作最小化、关闭等,代码如下;
  2. 因为是Razor组件,即html实现的界面,界面的html元素也定义了一些css样式,代码也一并给出 。
  3. 标题栏的按钮使用了一些svg图片,在仓库里 , 可自行获取 。
窗体拖动
首先添加NugetSimplify.Windows.Forms,用于获取鼠标光标的位置:
<PackageReference Include="Simplify.Windows.Forms" Version="1.1.2" />添加窗体帮助类:Services\WindowService.cs
using System;using System.Linq;using System.Windows;using System.Windows.Forms;using System.Windows.Threading;using Application = System.Windows.Application;namespace WPFBlazorChat.Services;public class WindowService{private static bool _isMoving;private static double _startMouseX;private static double _startMouseY;private static double _startWindLeft;private static double _startWindTop;public static void Init(){DispatcherTimer dispatcherTimer = new();dispatcherTimer.Tick += UpdateWindowPos;dispatcherTimer.Interval = TimeSpan.FromMilliseconds(17);dispatcherTimer.Start();}public static void StartMove(){_isMoving = true;_startMouseX = GetX();_startMouseY = GetY();var window = GetActiveWindow();if (window == null){return;}_startWindLeft = window.Left;_startWindTop = window.Top;}public static void StopMove(){_isMoving = false;}public static void Minimize(){var window = GetActiveWindow();if (window != null){window.WindowState = WindowState.Minimized;}}public static void Maximize(){var window = GetActiveWindow();if (window != null){window.WindowState =window.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;}}public static bool IsMaximized(){var window = GetActiveWindow();if (window != null){return window.WindowState == WindowState.Maximized;}return false;}public static void Close(bool allWindow = false){if (allWindow){Application.Current?.Shutdown();return;}var window = GetActiveWindow();if (window != null){window.Close();}}private static void UpdateWindowPos(object? sender, EventArgs e){if (!_isMoving){return;}double moveX = GetX() - _startMouseX;double moveY = GetY() - _startMouseY;Window? window = GetActiveWindow();if (window == null){return;}window.Left = _startWindLeft + moveX;window.Top = _startWindTop + moveY;}private static int GetX(){return Control.MousePosition.X;}private static int GetY(){return Control.MousePosition.Y;}private static Window? GetActiveWindow(){return Application.Current.Windows.Cast<Window>().FirstOrDefault(currentWindow => currentWindow.IsActive);}}上面的代码用于窗体的最小化、最大化(还原)、关闭等实现,需要在Razor组件里正确的调用这些方法:
  1. Counter.razor组件的OnInitialized初始化生命周期方法里调用WindowService.Init();,如上代码,这个方法开启定时器,定时调用UpdateWindowPos方法检查鼠标是否按下,如果按下,检查间隔内窗体的位置变化范围,然后修改窗体位置 , 从而实现窗体位置移动(移动窗体无法使用WPF的DragMove方法,您可以尝试使用看看它报什么错),移动窗体有更好的方法欢迎留言 。
  2. Razor组件里窗体控制按钮的使用看上面的代码不难理解,不过多解释 。
上面效果的样式文件修改如下,wwwroot\css\app.css
/*BlazorDesktopWPF-CustomTitleBar -Copyright 2021 - Jam-Es.comLicensed under the MIT License (MIT). See LICENSE in the repo root for license information.*/html, body {font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;padding: 0;margin: 0;}.valid.modified:not([type=checkbox]) {outline: 1px solid #26b050;}.invalid {outline: 1px solid red;}.validation-message {color: red;}#blazor-error-ui {background: lightyellow;bottom: 0;box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);display: none;left: 0;padding: 0.6rem 1.25rem 0.7rem 1.25rem;position: fixed;width: 100%;z-index: 1000;}#blazor-error-ui .dismiss {cursor: pointer;position: absolute;right: 0.75rem;top: 0.5rem;}.page-container {display: flex;flex-direction: column;height: 100vh;}.content-container {padding: 0px 20px 20px 20px;flex-grow: 1;overflow-y: scroll;}.titlebar {width: 100%;height: 32px;min-height: 32px;background-color: #7160E8;display: flex;flex-direction: row;}.titlebar-btn, .titlebar-cbtn {width: 46px;background-color: #7160E8;color: white;border: none;border-radius: 0;}.titlebar-btn:hover {background-color: #5A5A5A;}.titlebar-btn:focus, .titlebar-cbtn:focus {outline: 0;}.titlebar-cbtn:hover {background-color: #E81123;}.window-title {display: flex;flex-direction: column;justify-content: center;margin-left: 5px;color: white;}

推荐阅读