前言
关于 Blazor HybridElectron技术大家都很熟悉了,现在连QQ都用Electron重构了,在开发了相关项目之后,我也能理解这种做法,用前端技术来写界面真的爽,只要稍微牺牲一下性能,就可以获得不错的效果,而且现在电脑的性能都已经足够了,正好给web技术上桌面提供了条件。
而 Blazor 对于 C# 开发人员的优势是不需要学习各种 JavaScript 框架就可以开发交互式的 web 应用;虽然我做过不少前端项目,React也用得比较熟了,不过 Blazor Hybrid 还有一个优势是可以直接使用 C# 调用系统功能,Blazor Hybrid 一方面是运行在浏览器中,一方面又是直接在操作系统层面运行,C# 代码可以不受浏览器沙箱的限制,直接访问系统文件、设备等(虽然本项目中还是用到了Blazor与WinForms通信,不过那不是 C# 的功能限制,而是必须用到 WinForms 的功能)。
但是对于这个新技术,我们在实际开发过程中也会遇到一些坑,今天就记录一下使用 Blazor Hybrid 过程中遇到的几个问题,以及这个技术目前的一些局限性。
一.文件拖放事件的局限
Blazor Hybrid 的运行环境是 WebView,这导致了在处理文件拖放时出现了一些限制。在传统桌面应用中(如 WinForms 或 WPF),开发者可以直接捕获拖放事件,并获得文件的完整路径。但在 Blazor 中,拖放事件只能像浏览器中一样处理,意味着我们只能获得上传文件的流,而无法获取文件的实际路径。这对于那些需要直接访问文件路径的功能(如Clipify中把视频拖进去处理)带来了很大的不便。// 处理拖动进入事件,检测是否为文件 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; } } // 堆代码 duidaima.com // 处理拖放事件,获取文件路径 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; } }解决方案
3.重写微软提个的这个 Blazor Webview 控件,自己实现 WndProc 方法
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:我嫌麻烦就还没去折腾实现这个拖放功能,目前只做了打开对话框选择文件。
https://stackoverflow.com/questions/73197778/net-maui-blazor-app-drag-and-drop-impossible