前言

昨天写了一篇介绍 Blazor Hybrid 技术的文章,但限于篇幅,一些问题未能深入探讨。今天,我想继续记录使用 Blazor Hybrid 过程中遇到的几个问题,以及这个技术目前的一些局限性。

文件拖放事件的局限

Blazor Hybrid 的运行环境是 WebView,这导致了在处理文件拖放时出现了一些限制。在传统桌面应用中(如 WinForms 或 WPF),开发者可以直接捕获拖放事件,并获得文件的完整路径。但在 Blazor 中,拖放事件只能像浏览器中一样处理,意味着我们只能获得上传文件的流,而无法获取文件的实际路径。

这对于那些需要直接访问文件路径的功能(如Clipify中把视频拖进去处理)带来了很大的不便。

冗余代码(不是)

看了项目代码的同学可能会发现,FormMain.cs里还有处理拖放事件的代码,不过实际上并没有生效。

// 处理拖动进入事件,检测是否为文件
private void blazorWebView1_DragEnter(object sender, DragEventArgs e) {
Console.WriteLine("drag enter");
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
// 改变鼠标图标,表示可以拖放
e.Effect = DragDropEffects.Copy;
}
else {
e.Effect = DragDropEffects.None;
}
} // 处理拖放事件,获取文件路径
private void blazorWebView1_DragDrop(object sender, DragEventArgs e) {
Console.WriteLine("drag drop");
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
var files = (string[]?)e.Data.GetData(DataFormats.FileDrop); // 这里只处理单个文件,当然你也可以处理多个文件
if (files?.Length > 0) {
var filePath = files[0]; // 获取拖放的文件路径
MessageBox.Show($"文件路径: {filePath}"); // 在这里你可以将文件路径传递给 Blazor 或其他处理逻辑
}
}
} // 处理 DragOver 事件,防止系统默认行为
private void blazorWebView1_DragOver(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
e.Effect = DragDropEffects.Copy; // 明确允许拖放文件
}
else {
e.Effect = DragDropEffects.None;
}
}

解决方案

目前的解决办法有限,根据查找到的资料和我自己的探索,有以下几种:

  1. 在需要拖放的时候,使用一个WinForms原生控件覆盖webview
  2. 使用hook技术,拦截webview的拖放事件
  3. 重写微软提个的这个 Blazor Webview 控件,自己实现 WndProc 方法

第3种方法的代码大概是这样(未验证)

public class CustomBlazorWebView : BlazorWebView {
protected override void WndProc(ref Message m) {
const int WM_DROPFILES = 0x233; // 拖放文件消息 if (m.Msg == WM_DROPFILES) {
// 处理文件拖放逻辑
// 你可以在这里调用你的拖放事件处理逻辑 // 阻止消息传递,避免系统默认处理文件
return;
} base.WndProc(ref m);
}
}

PS:我嫌麻烦就还没去折腾实现这个拖放功能,目前只做了打开对话框选择文件。

社区反馈

同样的问题我在 Github issues 和 Stack Overflow 之类的平台也有看到很多人提出,不过看起来微软并不想解决这些问题。

相关链接:

桌面应用体验差异

Blazor Hybrid 尽管以桌面应用的形式运行,但表现更接近于网页应用。

浏览器的快捷键

一个明显的例子是,在 WebView 中按下 F5 键时,页面会像浏览器一样刷新,这种行为显然不符合传统桌面软件的用户体验。

在类似的技术中,如 Electron,也存在类似的局限。但不同的是,Electron 提供了更多对浏览器行为的控制手段,可以阻止或重定义这些行为,而 Blazor Hybrid 目前则没有这些更细粒度的控制能力。

从桌面应用的角度来看,用户希望获得一致且原生的操作体验,因此这些细微的差异可能会影响开发者对 Blazor Hybrid 应用的期望。

窗口大小调整的表现

在使用 Blazor Hybrid 时,我还注意到窗口大小调整的流畅度问题。相比起原生的桌面应用,Blazor Hybrid 的表现不尽如人意。当用户调整窗口大小时,界面偶尔会出现黑边或画面撕裂的现象。

这种问题不仅在 Blazor Hybrid 中出现,实际上,在浏览器(chrome)和 Electron 应用(QQ)中,我也观察到类似的问题。

为了更深入地理解这个现象,我还测试了 C++ 原生应用,结果发现原生应用在调整窗口大小时相对来说更流畅,没有出现黑边或撕裂的问题。

我猜测造成这种差异的原因可能在于,Blazor Hybrid 和 Electron 依赖 WebView 作为渲染引擎,而 WebView 的渲染机制在处理窗口大小调整时不如原生 UI 渲染引擎高效。

小结

Blazor Hybrid 是一个非常有潜力的技术,它让 C# 开发者能够轻松地构建跨平台桌面应用。

然而,在使用过程中,我发现了一些需要关注的问题,尤其是在拖放事件、桌面应用行为一致性和窗口大小调整表现上。

这些问题目前可能对开发者造成一定的困扰,也影响了用户体验的流畅性。

接下来我会找时间试一下 Electron 和 wails 的开发体验,进一步探索 Blazor Hybrid 在桌面软件开发中的优势。

Blazor Hybrid 实战体验:那些你可能没预料到的坑没预料到的坑的更多相关文章

  1. Blazor Hybrid / MAUI 简介和实战

    1. Blazor Blazor 是一个使用 .NET 生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建信息丰富的交互式 UI. 共享使用 .NET 编写的服务 ...

  2. 转【实战体验几种MySQLCluster方案】

    实战体验几种MySQLCluster方案 1.背景 MySQL的cluster方案有很多官方和第三方的选择,选择多就是一种烦恼,因此,我们考虑MySQL数据库满足下三点需求,考察市面上可行的解决方案: ...

  3. 网络资源管理系统LANsurveyor实战体验

    网络资源管理系统LANsurveyor实战体验 用于生成网络拓扑并管理网络各种设备的软件很多(例如上一篇文章展示的CiscoWorks 2000,我还介绍过开源领域的Cheops-NG),今天为大家介 ...

  4. 构建企业级数据湖?Azure Data Lake Storage Gen2实战体验(中)

    引言 相较传统的重量级OLAP数据仓库,“数据湖”以其数据体量大.综合成本低.支持非结构化数据.查询灵活多变等特点,受到越来越多企业的青睐,逐渐成为了现代数据平台的核心和架构范式. 因此数据湖相关服务 ...

  5. 构建企业级数据湖?Azure Data Lake Storage Gen2实战体验(下)

    相较传统的重量级OLAP数据仓库,“数据湖”以其数据体量大.综合成本低.支持非结构化数据.查询灵活多变等特点,受到越来越多企业的青睐,逐渐成为了现代数据平台的核心和架构范式. 作为微软Azure上最新 ...

  6. Bootstrap Blazor Viewer 图片浏览器 组件更新, 支持流转图片(ImageFromStream), 用于本地项目例如 MAUI Blazor,Blazor hybrid

    示例: https://blazor.app1.es/viewer 使用方法: 1.nuget包 BootstrapBlazor.Viewer 2._Imports.razor 文件 或者页面添加 添 ...

  7. Blazor Hybrid (Blazor混合开发)更好的读取本地图片

    在 Blazor Hybrid 应用中,Razor 组件在设备上本机运行. 组件通过本地互操作通道呈现到嵌入式 Web View 控件. 组件不在浏览器中运行,并且不涉及 WebAssembly. R ...

  8. 微信小程序没找到构建npm或者没找到node_modules目录以及如何在小程序中引入vant weapp组件

    微信小程序没找到构建npm或者没找到node_modules目录解决方法如下: 按照微信小程序提供的文档npm install是不行的,直接提示没找到可构建的npm包. 1.直接安装:npm init ...

  9. Windows 和 Ubuntu 的网络能互相 ping 通之后,linux无法上网原因:①路由没设置好,②DNS 没设置好

    确保 Windows 和 Ubuntu 的网络能互相 ping 通之后,如果 Ubuntu 无法上网,原因通常有 2 个:路由没设置好,DNS 没设置好. 如果执行以下命令不成功,表示路由没设置好: ...

  10. 浏览器中的 .Net Core —— Blazor WebAssembly 初体验

    前言 在两年多以前就听闻 Blazor 框架,是 .Net 之父的业余实验性项目,其目的是探索 .Net 与 WebAssembly 的兼容性和应用前景.现在这个项目已经正式成为 Asp.Net Co ...

随机推荐

  1. tmux使用教程:终端神器tmux:多任务管理大师

    文字版教程: 阮一峰 Tmux 使用教程 视频教程: 终端神器tmux:多任务管理大师

  2. 服务器上运行 xvbf 时报错 —— Unknown encoder 'libx264'

    解决方法: 使用conda环境(不具体交代) conda install ffmpeg 成功运行:

  3. 【转载】 DQN玩Atari游戏安装atari环境bug指南

    版权声明:本文为CSDN博主「好程序不脱发」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/ningmengzh ...

  4. 苹果系统Mac升级后之前的网络软件不可用——Mac系统维护——Mac系统升级后软件报错——mac系统升级后导致软件兼容报错

    ========================================== 博士同学最近联系我,说是自己的mac系统升级后之前可以用的网络软件不可用使用了,由于平时工作需要,这个网络软件如果 ...

  5. xshell打开vim后颜色异常——xshell连接ubuntu打开vim后界面覆盖一层绿色

    参考原文: https://blog.csdn.net/Blank_Shen/article/details/106527312 =================================== ...

  6. 9组-Beta冲刺-5/5

    一.基本情况(15分) 队名:不行就摆了吧 组长博客:9组-Beta冲刺-5/5 GitHub链接:https://github.com/miaohengming/studynote/tree/mai ...

  7. C# ?. 判斷Null值

    有一句代碼: @Html.DisplayFor(modelItem => item.SellDate, "RegularDate") RegularDate.cshtml 內 ...

  8. SMU 2024 spring 天梯赛自主训练1

    SMU 2024 spring 天梯赛自主训练1 7-1 宇宙无敌大招呼 - SMU 2024 spring 天梯赛自主训练1 (pintia.cn) #include <bits/stdc++ ...

  9. 安卓如何设置开机启动某个程序?init.rc给你搞定

    一.如何设置开机启动某个程序? 1.需求描述 最近有个项目需要在Android开机启动之后,自动执行一个C语言编写的程序:pengd 该程序运行时需要修改网络ip地址及其他网络操作,所以需要root权 ...

  10. Camera | 9.如何让camera支持闪光灯?-基于rk3568

    一.闪光灯基本原理 工作模式 Camera flash led分flash和torch两种模式. flash: 拍照时上光灯瞬间亮一下,电流比较大,目前是1000mA,最大电流不能超过led最大承受能 ...