.NET 創(chuàng)建無邊框的跨平臺應(yīng)用
在創(chuàng)建了Photino
應(yīng)用程序以后我們發(fā)現(xiàn)它自帶了一個標題欄,并且非常丑,我們現(xiàn)在要做的就是去掉這個很丑的自帶標題欄,并且自定義一個更好看的,下面我們將用Masa Blazor
提供的模板去進行實戰(zhàn)。
安裝模板
安裝Masa Blazor
提供的rc2
的模板
dotnet new install Masa.Template::1.0.0-rc.2
創(chuàng)建項目
- 打開VS2022 => 新建項目
- 搜索到一下類別!
- 然后創(chuàng)建
Gotrays
名稱的項目
項目結(jié)構(gòu)
無邊框處理
修改Program.cs
代碼,增加SetChromeless
,設(shè)置無邊框
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();
}
}
啟動以后的效果:
這樣就完成了我們的無邊框,但是也并不是直接可以使用,你會發(fā)現(xiàn)它無法拖動!下面我們將讓他可以被拖動
完善無邊框拖動
我們需要支持拖動我們的標題欄的時候帶動我們的窗口!
下面開始修改代碼實現(xiàn)這個邏輯
我們的標題欄的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 rel="stylesheet">
<link rel="stylesheet">
<link 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的代碼是為了傳遞窗口拖動參數(shù)實現(xiàn)實際的拖動
<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; }
}
代碼實現(xiàn)邏輯
-
首先需要定義css樣式,這個是相當于指定了哪個元素可以被拖動
#app .m-app-bar { -webkit-app-region: drag; }
-
然后定義js腳本,通過js去監(jiān)聽拖動的事件然后計算坐標,將計算好的坐標傳遞到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
的元素被鼠標按下的時候?qū)τ?code>pageX = e.pageX,pageY = e.pageY
,start = true
三個值賦值,start
表示鼠標按下并且啟動拖動,pageX
和pageY
則是鼠標首次按下坐標當元素被
mousedown
觸發(fā)將拖動的坐標和首次點擊的坐標相減,然后就可以通過window.external.sendMessage
傳遞到c#的代碼塊中,先判斷Message
的數(shù)據(jù)是否為json,如果是則轉(zhuǎn)換模型,然后計算設(shè)置實際窗體的位置即可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)); } }
效果
結(jié)尾
來著token的分享文章來源:http://www.zghlxwxcb.cn/news/detail-463299.html
技術(shù)交流群:737776595文章來源地址http://www.zghlxwxcb.cn/news/detail-463299.html
到了這里,關(guān)于.NET 創(chuàng)建無邊框的跨平臺應(yīng)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!