Search code examples
mauimaui-community-toolkit.net-maui.shell

How to Pass a String Value from MAUI Shell to a Blazor Component Parameter in a MAUI Blazor hybrid App?


I am developing an app using .NET MAUI Blazor, where I have a Shell with the following code in MainPage.xaml. I also have a Blazor page named ListOfTask that lists tasks. Below is the code for that Blazor page. I want to know how to pass a string value from the MAUI Shell to a parameter in the ListOfTask Blazor component. This is my first time writing an app, so I'm learning as I go. Please excuse any logical errors—this is just a test app." **

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>

**

My ListOfTask blazor page

**

@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);
    }
}

If you see i am passing the test value to await App.Current.MainPage.Navigation.PushAsync(new NewPage1("test" ); which is also calling a blazor page

<?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>

**


**

@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;
    }
}

is it a way i get that value in my blazor parameter MyProperty


Solution

  • Potentially, there're two methods that you can pass a String Value from MAUI to a Blazor Component.

    #1:

    You may define your MainPage.xaml using ContentPage, so you can pass it through constructor.

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:MauiBlazorWindow.Components.Pages"
                 x:Class="MauiBlazorWindow.MainPage">
    
        <BlazorWebView x:Name="blazorWebView" HostPage="wwwroot/index.html">
            <BlazorWebView.RootComponents>
                <RootComponent x:Name="root"  Selector="#app" ComponentType="{x:Type local:Home}" />
            </BlazorWebView.RootComponents>
        </BlazorWebView>
    
    </ContentPage>
    
    
    public partial class MainPage : ContentPage
    {
         public string myPassString = "This is a string";
         public MainPage()
         {
              InitializeComponent();
              root.Parameters = new Dictionary<string, object>()
              {
                    {"MyProperty",myPassString }
               };
              
         }    
    }
    

    In your Blazor Component, define a [Parameter] variable and then you can receive it via @MyProperty.

    @code {
        [Parameter]
        public string MyProperty { get; set; }
    

    #2:

    Define a string myPassString that you want to pass below in your MainPage.xaml.cs:

    public string myPassString = "This is a string";
    

    And then pass it to MyProperty:

    @code {
        [Parameter]
        public string MyProperty { get; set; }
    
        protected override void OnInitialized()
        {
            base.OnInitialized();
            MyProperty = (App.Current.MainPage as MainPage).myPassString;
        }