You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:25:22