在创建了Photino
应用程序以后我们发现它自带了一个标题栏,并且非常丑,我们现在要做的就是去掉这个很丑的自带标题栏,并且自定义一个更好看的,下面我们将用Masa Blazor
提供的模板去进行实战。
安装Masa Blazor
提供的rc2
的模板
dotnet new install Masa.Template::1.0.0-rc.2
Gotrays
名称的项目修改Program.cs
代码,增加SetChromeless
,设置无边框
using Gotrays; using Microsoft.Extensions.DependencyInjection; using Photino.Blazor; internal class Program { [STAThread] private static void Main(string[] args) { var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args); appBuilder.RootComponents.Add<App>("#app"); appBuilder.Services.AddMasaBlazor(); var app = appBuilder.Build(); app.MainWindow .SetTitle("Photino Blazor Sample") .SetChromeless(true); AppDomain.CurrentDomain.UnhandledException += (sender, error) => { }; app.Run(); } }
启动以后的效果:
这样就完成了我们的无边框,但是也并不是直接可以使用,你会发现它无法拖动!下面我们将让他可以被拖动
我们需要支持拖动我们的标题栏的时候带动我们的窗口!
下面开始修改代码实现这个逻辑
我们的标题栏的css的样式是m-app-bar
打开wwwroot/index.html
并且修改为以下代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" /> <title>Gotrays</title> <base href="/" /> <link href="_content/Masa.Blazor/css/masa-blazor.min.css" rel="stylesheet"> <link href="css/app.css" rel="stylesheet" /> <link href="Gotrays.styles.css" rel="stylesheet" /> <link href="https://cdn.masastack.com/npm/@mdi/font@7.1.96/css/materialdesignicons.min.css" rel="stylesheet"> <link href="https://cdn.masastack.com/npm/materialicons/materialicons.css" rel="stylesheet"> <link href="https://cdn.masastack.com/npm/fontawesome/v5.0.13/css/all.css" rel="stylesheet"> <style> #app .m-app-bar { -webkit-app-region: drag; } html { overflow: hidden; } </style> </head> <body> <div class="status-bar-safe-area"></div> <div id="app">Loading...</div> <div id="blazor-error-ui"> An unhandled error has occurred. <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.webview.js"></script> <script src="_content/BlazorComponent/js/blazor-component.js"></script> <script> let start = false; let pageX = 0; let pageY = 0; document.body.addEventListener('mousedown', evt => { const { target } = evt; const appRegion = getComputedStyle(target)['-webkit-app-region']; const app = document.getElementById("m-app-bar"); app.addEventListener('mousemove', onmousemove) app.addEventListener("mousedown", (e) => { console.log(e.pageX, e.pageY); pageX = e.pageX; pageY = e.pageY; start = true; }) app.addEventListener("mouseup", (e) => { start = false; }) console.log("MouseDownDrag", evt, appRegion, app); if (appRegion === 'drag') { var data = { Command: "MouseMove", Data: { } } evt.preventDefault(); evt.stopPropagation(); } }); function onmousemove(e) { if (start) { console.log("MouseMove", e); var data = { "Command": "MouseMove", X: e.clientX - pageX, Y: e.clientY - pageY } window.external.sendMessage(JSON.stringify(data)); } } </script> </body> </html>
主要是添加了这个样式文件,注意的是这个相当于标记了哪个可以拖动我们的窗口的标记
<style> #app .m-app-bar { -webkit-app-region: drag; } html { overflow: hidden; } </style>
下面的js的代码是为了传递窗口拖动参数实现实际的拖动
<script> let start = false; let pageX = 0; let pageY = 0; document.body.addEventListener('mousedown', evt => { const { target } = evt; const appRegion = getComputedStyle(target)['-webkit-app-region']; const app = document.getElementById("m-app-bar"); app.addEventListener('mousemove', onmousemove) app.addEventListener("mousedown", (e) => { console.log(e.pageX, e.pageY); pageX = e.pageX; pageY = e.pageY; start = true; }) app.addEventListener("mouseup", (e) => { start = false; }) console.log("MouseDownDrag", evt, appRegion, app); if (appRegion === 'drag') { var data = { Command: "MouseMove", Data: { } } evt.preventDefault(); evt.stopPropagation(); } }); function onmousemove(e) { if (start) { console.log("MouseMove", e); var data = { "Command": "MouseMove", X: e.clientX - pageX, Y: e.clientY - pageY } window.external.sendMessage(JSON.stringify(data)); } } </script>
修改Program.cs
文件的代码支持拖动
using System.Diagnostics; using Gotrays; using Microsoft.Extensions.DependencyInjection; using Photino.Blazor; using PhotinoNET; using System.Runtime.InteropServices; using System.Text.Json; internal class Program { [STAThread] private static void Main(string[] args) { var appBuilder = PhotinoBlazorAppBuilder.CreateDefault(args); appBuilder.RootComponents.Add<App>("#app"); appBuilder.Services.AddMasaBlazor(); var app = appBuilder.Build(); app.MainWindow .SetTitle("Photino Blazor Sample") .SetChromeless(true) .RegisterWebMessageReceivedHandler(MessageReceived); AppDomain.CurrentDomain.UnhandledException += (sender, error) => { }; app.Run(); } private static void MessageReceived(object? sender, string message) { var window = sender as PhotinoWindow; if (message.StartsWith("{")) { var data = JsonSerializer.Deserialize<Message>(message); if (data == null || data.Command != "MouseMove") return; var left = window.Left + data.X; var top = window.Top + data.Y; if (left <= -window.Width / 2) { left = -window.Width / 2; } if (window.Top < 0) { window.Top = 0; } window.SetLeft((int)((int)left)); window.SetTop((int)((int)top)); } } } public class Message { public string Command { get; set; } public double X { get; set; } public double Y { get; set; } }
代码实现逻辑
首先需要定义css样式,这个是相当于指定了哪个元素可以被拖动
#app .m-app-bar { -webkit-app-region: drag; }
然后定义js脚本,通过js去监听拖动的事件然后计算坐标,将计算好的坐标传递到c#的事件中完成实际的窗体拖动事件
let start = false; let pageX = 0; let pageY = 0; document.body.addEventListener('mousedown', evt => { const { target } = evt; const appRegion = getComputedStyle(target)['-webkit-app-region']; const app = document.getElementById("m-app-bar"); app.addEventListener('mousemove', onmousemove) app.addEventListener("mousedown", (e) => { pageX = e.pageX; pageY = e.pageY; start = true; }) app.addEventListener("mouseup", (e) => { start = false; }) if (appRegion === 'drag') { var data = { Command: "MouseMove", Data: { } } evt.preventDefault(); evt.stopPropagation(); } }); function onmousemove(e) { if (start) { console.log("MouseMove", e); var data = { "Command": "MouseMove", X: e.clientX - pageX, Y: e.clientY - pageY } window.external.sendMessage(JSON.stringify(data)); } }
当id为m-app-bar
的元素被鼠标按下的时候对于pageX = e.pageX
,pageY = e.pageY
,start = true
三个值赋值,start
表示鼠标按下并且启动拖动,pageX
和pageY
则是鼠标首次按下坐标
当元素被mousedown
触发将拖动的坐标和首次点击的坐标相减,然后就可以通过window.external.sendMessage
传递到c#的代码块中,先判断Message
的数据是否为json,如果是则转换模型,然后计算设置实际窗体的位置即可
private static void MessageReceived(object? sender, string message) { var window = sender as PhotinoWindow; if (message.StartsWith("{")) { var data = JsonSerializer.Deserialize<Message>(message); if (data == null || data.Command != "MouseMove") return; var left = window.Left + data.X; var top = window.Top + data.Y; if (left <= -window.Width / 2) { left = -window.Width / 2; } if (window.Top < 0) { window.Top = 0; } window.SetLeft((int)((int)left)); window.SetTop((int)((int)top)); } }
来着token的分享
技术交流群:737776595