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

.NET MAUI Blazor:如何从Shell传递字符串到Blazor组件参数

问题描述

我正在开发.NET MAUI Blazor混合应用,现有MainPage.xaml中的Shell代码,以及用于展示任务的ListOfTask Blazor页面。当前在ListOfTask中通过await App.Current.MainPage.Navigation.PushAsync(new NewPage1("test"))跳转到NewPage1,希望将该"test"字符串传递到/task1 Blazor页面中由[Parameter]修饰的MyProperty参数中,请教实现方法。

相关代码

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiApp14"
             x:Class="MauiApp14.MainPage"
             xmlns:pages="clr-namespace:MauiApp14.Components.Pages"
             xmlns:pagese="clr-namespace:MauiApp14.Components.Pages.Survey"
             xmlns:in="clr-namespace:MauiApp14.Components.Layout"
             >
    <TabBar>
        <!--<ShellContent Title="Settings" Icon="settings.png" ContentTemplate="{DataTemplate pages:NewPage4}" />-->

        <ShellContent Title="Home" Icon="icons_task.png">
            <ContentPage>
                <BlazorWebView x:Name="Survey" HostPage="wwwroot/index.html">
                    <BlazorWebView.RootComponents>
                        <RootComponent Selector="#app" ComponentType="{x:Type pagese:ListOftask}" />
                    </BlazorWebView.RootComponents>
                </BlazorWebView>
            </ContentPage>
        </ShellContent>

    </TabBar>

</Shell>

ListOfTask Blazor页面

@page "/tasklist"
@using MauiApp14.Components.Layout
@inject NavigationManager navigationManager

<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>Task Name</th>
            <th>Description</th>
            <th>Actions</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var task in tasks)
        {
            <tr>
                <td>@task.Id</td>
                <td>@task.Name</td>
                <td>@task.Description</td>
                <td>
                    <button class="btn btn-primary" @onclick="() => StartTask(task)">Start</button>
                </td>
            </tr>
        }
    </tbody>
</table>

@code {
    private List<TaskModel> tasks;

    protected override void OnInitialized()
    {
        // Initialize the list of tasks
        tasks = new List<TaskModel>
        {
            new TaskModel { Id = 1, Name = "Task 1", Description = "Description for Task 1", RedirectUrl = "/task1" },
            new TaskModel { Id = 2, Name = "Task 2", Description = "Description for Task 2", RedirectUrl = "/task1" },
            new TaskModel { Id = 3, Name = "Task 3", Description = "Description for Task 3", RedirectUrl = "/task1" },
            // Add more tasks as needed
        };
    }

    private async Task StartTask(TaskModel task)
    {
        await App.Current.MainPage.Navigation.PushAsync(new NewPage1("test") );
        //  navigationManager.NavigateTo(task.RedirectUrl,true);
    }
}

NewPage1.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp14.Components.NewPage1"
             Title="Survey"
             xmlns:pages="clr-namespace:MauiApp14.Components.Pages">

    <StackLayout>
        <!-- Entry (TextBox) for user input -->
        <Entry x:Name="entryTextBox" Placeholder="Enter text here" />

        <!-- BlazorWebView to display Blazor content -->
        <BlazorWebView x:Name="blazorWebView4" HostPage="wwwroot/index.html">
            <BlazorWebView.RootComponents>
                <RootComponent Selector="#app" ComponentType="{x:Type pages:Counter}" />
            </BlazorWebView.RootComponents>
        </BlazorWebView>
    </StackLayout>

</ContentPage>

/task1 Blazor页面

@page "/task1"
@using MauiApp14.Components.Layout
@inject Radzen.DialogService DialogService
@inject NavigationManager navigationManager
@inject DataTransferService DataTransferService

<div style="padding-bottom: 60px;">
    <!-- Adjust padding-bottom as needed -->
    <div class="rz-p-0 rz-p-md-12">
        <RadzenStack Orientation="Orientation.Horizontal" FlexWrap="FlexWrap.Wrap" Gap="1rem" class="rz-p-4 rz-mb-6">
            <RadzenTimeline Orientation="@orientation" LinePosition="LinePosition.Start"
                            style="--rz-timeline-line-width: 3px;
                           --rz-timeline-line-color: var(--rz-info);
                           --rz-timeline-axis-size: 72px;
                           max-width: 600px;
                           margin: 0 auto;">
                <Items>
                    @foreach (var step in Steps)
                    {
                        <RadzenTimelineItem PointVariant="Variant.Outlined" PointStyle="@step.PointStyle" PointShadow="@step.PointShadow">
                            <PointContent><RadzenIcon Icon="@step.Icon" /></PointContent>
                            <ChildContent>
                                <RadzenText TextStyle="TextStyle.Subtitle1" class="rz-m-0">Step @step.Id</RadzenText>
                                <RadzenText TextStyle="TextStyle.Body2" class="rz-m-0">@step.Title</RadzenText>
                            </ChildContent>
                        </RadzenTimelineItem>
                    }
                </Items>
            </RadzenTimeline>
        </RadzenStack>
    </div>

    @if (!isComplete)
    {
        <!-- Symptom Check Dialog -->
        <SymptomCheckDialog OnNext="HandleNext" />
    }
    else
    {
        <MauiApp14.Components.Pages.Survey.Complete />
    }
    <button class="btn btn-primary" @onclick="GoBack">@MyProperty</button>

</div>

@code {

    [Parameter]
    public string MyProperty { get; set; } 
    private async Task GoBack()
    {
        // Navigate back to the previous page
        await App.Current.MainPage.Navigation.PopToRootAsync();
    }
    public List<UserTask> Steps { get; set; } = new List<UserTask>();
    private bool isComplete = false;

    protected override Task OnInitializedAsync()
    {
        MyProperty = DataTransferService.EntryText;
     

        return base.OnInitializedAsync();
    }

    private void HandleNext()
    {
        isComplete = true;
        Steps.ForEach(step =>
        {
            if (step.Title == "Complete Your Profile")
            {
                step.PointStyle = PointStyle.Warning;
            }
            else
            {
                step.PointStyle = PointStyle.Primary;
            }
        });
        StateHasChanged(); // Refresh the UI to show the Complete component
    }

    Orientation orientation = Orientation.Horizontal;

    public class UserTask
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public bool LeftOn { get; set; } = false;
        public string Icon { get; set; }
        public int PointShadow { get; set; } = 0;
        public PointStyle PointStyle { get; set; } = PointStyle.Info;
    }
}
解决方案

要实现将"test"传递到/task1页面的MyProperty参数,可通过以下两种方式完成:

方式1:使用共享服务传递数据(推荐)

利用你已有的DataTransferService,通过服务在页面间共享数据:

1. 注册共享服务

确保DataTransferService在MauiProgram.cs中注册为单例:

builder.Services.AddSingleton<DataTransferService>();

2. 修改NewPage1代码后台

在NewPage1.xaml.cs中接收传入的值并存入服务,同时修改BlazorWebView加载/task1页面:

public partial class NewPage1 : ContentPage
{
    private readonly DataTransferService _dataTransferService;

    public NewPage1(string passedValue, DataTransferService dataTransferService)
    {
        InitializeComponent();
        _dataTransferService = dataTransferService;
        // 将传递的值存入服务
        _dataTransferService.EntryText = passedValue;
        
        // 替换原有RootComponent为/task1页面
        blazorWebView4.RootComponents.Clear();
        blazorWebView4.RootComponents.Add(new RootComponent("#app", typeof(MauiApp14.Components.Pages.task1), null));
    }
}

3. 修改ListOfTask的跳转逻辑

通过依赖注入获取服务实例,创建NewPage1:

@inject IServiceProvider ServiceProvider

private async Task StartTask(TaskModel task)
{
    var dataService = ServiceProvider.GetRequiredService<DataTransferService>();
    var newPage = new NewPage1("test", dataService);
    await App.Current.MainPage.Navigation.PushAsync(newPage);
}

4. 保持/task1页面的初始化逻辑

/task1页面中已有的OnInitializedAsync代码可以直接使用,会自动从服务中获取值:

protected override Task OnInitializedAsync()
{
    MyProperty = DataTransferService.EntryText;
    return base.OnInitializedAsync();
}

方式2:直接给Blazor组件传递参数

跳过服务,直接在初始化Blazor组件时传入参数:

1. 修改NewPage1代码后台

public partial class NewPage1 : ContentPage
{
    public NewPage1(string passedValue)
    {
        InitializeComponent();
        
        // 替换RootComponent并传递参数
        blazorWebView4.RootComponents.Clear();
        var parameters = new Dictionary<string, object>
        {
            { "MyProperty", passedValue }
        };
        blazorWebView4.RootComponents.Add(new RootComponent("#app", typeof(MauiApp14.Components.Pages.task1), parameters));
    }
}

2. 修改ListOfTask的跳转逻辑

private async Task StartTask(TaskModel task)
{
    var newPage = new NewPage1("test");
    await App.Current.MainPage.Navigation.PushAsync(newPage);
}

3. 调整/task1页面的初始化逻辑

注释掉从服务取值的代码,让Blazor自动绑定参数:

protected override Task OnInitializedAsync()
{
    // MyProperty = DataTransferService.EntryText; // 注释此行
    return base.OnInitializedAsync();
}

关键注意事项

  • 必须确保NewPage1中的BlazorWebView加载的是/task1页面,而非原来的Counter页面,否则参数传递无效。
  • 使用共享服务时,必须注册为单例或作用域,保证数据在页面间共享。
  • 直接传参时,参数名必须与Blazor组件中[Parameter]修饰的属性名完全一致(此处为MyProperty)。

内容的提问来源于stack exchange,提问作者ZCoder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:49:53