.NET MAUI中BlazorWebView调用Razor组件C#方法的实现
在.NET MAUI BlazorWebView中从原生页面调用Blazor组件方法
方法一:通过静态实例直接调用(简单直接)
这种方式适合小型项目或快速原型开发,直接在Blazor组件中暴露静态实例供原生页面调用。
1. 修改Blazor组件(index.razor)
优化TerminalWrite方法并添加静态实例引用:
@page "/" @implements IAsyncDisposable <h1>Hello, world!</h1> Welcome to your new app. <Xterm @ref="_terminal" Options="_options" AddonIds="_addonIds" OnFirstRender="@OnFirstRender" /> @code { private Xterm _terminal; // 暴露静态实例供原生页面访问 public static Main Instance { get; private set; } private TerminalOptions _options = new TerminalOptions { CursorBlink = true, CursorStyle = CursorStyle.Bar, }; private string[] _addonIds = new string[] { "xterm-addon-fit", }; protected override void OnInitialized() { Instance = this; base.OnInitialized(); } private async Task OnFirstRender() { await _terminal.InvokeAddonFunctionVoidAsync("xterm-addon-fit", "fit"); await _terminal.WriteLine("Hello World"); } // 将async void改为async Task,避免异步操作的潜在问题 public async Task TerminalWrite(string key) { await _terminal.Write(key); } public ValueTask DisposeAsync() { // 组件销毁时清空实例引用 if (Instance == this) Instance = null; return ValueTask.CompletedTask; } }
2. 修改MAUI原生页面(MainPage.xaml.cs)
在按钮命令中调用Blazor组件的方法:
public partial class MainPage : ContentPage { public ICommand DigitCommand { set; get; } public MainPage() { InitializeComponent(); DigitCommand = new Command<string>(async (string arg) => { // 检查组件实例是否已初始化 if (TestBlazorApp.Main.Instance != null) { // 调用Blazor组件的TerminalWrite方法,传入自定义内容 await TestBlazorApp.Main.Instance.TerminalWrite("Button Clicked!"); } }); } }
方法二:使用消息中心解耦(推荐复杂场景)
通过CommunityToolkit.Mvvm的消息中心实现原生页面与Blazor组件的解耦通信,避免直接依赖组件实例。
1. 安装NuGet包
在项目中安装CommunityToolkit.Mvvm包:
Install-Package CommunityToolkit.Mvvm
2. 创建消息类
定义用于传递命令的消息:
using CommunityToolkit.Mvvm.Messaging.Messages; namespace TestBlazorApp { public class TerminalWriteMessage : ValueChangedMessage<string> { public TerminalWriteMessage(string value) : base(value) { } } }
3. 修改Blazor组件订阅消息
在Blazor组件中订阅消息并响应:
@page "/" @implements IAsyncDisposable @inject CommunityToolkit.Mvvm.Messaging.IMessenger Messenger <h1>Hello, world!</h1> Welcome to your new app. <Xterm @ref="_terminal" Options="_options" AddonIds="_addonIds" OnFirstRender="@OnFirstRender" /> @code { private Xterm _terminal; private IDisposable _messageSubscription; private TerminalOptions _options = new TerminalOptions { CursorBlink = true, CursorStyle = CursorStyle.Bar, }; private string[] _addonIds = new string[] { "xterm-addon-fit", }; protected override void OnInitialized() { // 订阅TerminalWriteMessage消息 _messageSubscription = Messenger.Register<TerminalWriteMessage>(this, (recipient, message) => { _ = recipient.TerminalWrite(message.Value); }); base.OnInitialized(); } private async Task OnFirstRender() { await _terminal.InvokeAddonFunctionVoidAsync("xterm-addon-fit", "fit"); await _terminal.WriteLine("Hello World"); } public async Task TerminalWrite(string key) { await _terminal.Write(key); } public ValueTask DisposeAsync() { // 取消订阅消息 _messageSubscription?.Dispose(); return ValueTask.CompletedTask; } }
4. 修改MAUI原生页面发送消息
在按钮命令中发送消息触发Blazor组件方法:
using CommunityToolkit.Mvvm.Messaging; namespace TestBlazorApp { public partial class MainPage : ContentPage { public ICommand DigitCommand { set; get; } public MainPage() { InitializeComponent(); DigitCommand = new Command<string>(async (string arg) => { // 发送消息,传递要写入终端的内容 WeakReferenceMessenger.Default.Send(new TerminalWriteMessage("Clicked via Messenger!")); }); } } }
内容的提问来源于stack exchange,提问作者Gabriel Duchateau
相关产品推荐
相关产品推荐

