Blazor Hybrid 实战体验:那些你可能没预料到的坑

前言#

昨天写了一篇介绍 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 在桌面软件开发中的优势。

作者:DealiAxy

出处:https://www.cnblogs.com/deali/p/18458357

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

微信公众号:「程序设计实验室」
新版StarBlog已经上线,地址:http://blog.deali.cn

posted @   程序设计实验室  阅读(714)  评论(9编辑  收藏  举报
相关博文:
阅读排行:
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· DeepSeek本地性能调优
· 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示