前言

昨天写了一篇介绍 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. 【Spring-Security】Re07 持久化的记住我

    Security记住我功能底层实现依赖于SpringJDBC组件,如果有持久层框架的话,就由持久层框架实现 演示案例的选型,MysqlJdbc + MybatisStarter <depende ...

  2. 【TypeScript】02 面向对象

    [联合类型] 联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值. 注意:只能赋值指定的类型,如果赋值其它类型就会报错. var val:strin ...

  3. 全网最适合入门的面向对象编程教程:30 Python的内置数据类型-object根类

    全网最适合入门的面向对象编程教程:30 Python 的内置数据类型-object 根类 摘要: 在 Python 中,所有的类都直接或间接继承自一个根类,这个根类是Object.Object类是 P ...

  4. Singleton bean creation not allowed while singletons of this factory are in destruction

    1.背景 一直都是正常运行的程序,检查日志发现有一条报错如下: org.springframework.beans.factory.BeanCreationNotAllowedException: E ...

  5. 圆方树学习笔记 & 最短路 题解

    前言 圆方树学习笔记,从一道例题讲起. 题目链接:Hydro & bzoj. 题意简述 仙人掌上求两点距离. 题目分析 为了把仙人掌的性质发挥出来,考虑将其变成一棵树.圆方树就是这样转换的工具 ...

  6. 一文搞懂DevOps、DataOps、MLOps、AIOps:所有“Ops”的比较

    引言 近年来,"Ops"一词在 IT 运维领域的使用迅速增加.IT 运维正在向自动化过程转变,以改善客户交付.传统的应用程序开发采用 DevOps 实施持续集成(CI)和持续部署( ...

  7. windows编程中文件操作的几种方法,C,C++,MFC,Win32sdk

    windows编程中文件操作的几种方法 windows编程中文件操作有以下几种常见方法: 1.C语言中文件操作.2.C++语言中的文件操作.3.Win32 API函数文件操作.4.MFC CFile类 ...

  8. C#ListView类的继承

    ListView控件类新加方法 新建一个类myListView class myListView : System.Windows.Forms.ListView { //添加自定义的方法 -- //设 ...

  9. 什么是电商API

    ​ 是电子商务平台提供给开发者和商家的一种技术接口,它允许第三方应用程序访问和操作平台的数据和服务.电商API的使用可以极大地提高业务效率,促进创新,并且为商家提供更多的商业机会. 以下是电商API的 ...

  10. 四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如何关联 Spring 容器) 以及个人编写启动 Tomcat

    四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如何关联 Spring 容器) 以及个人编写启动 Tomcat @ 目录 四,分析Spring Bo ...