Search code examples
c#xamlblazormauimaui-blazor

Is there a way to pass parameters back from a Blazor component in a BlazorWebView to the code behind of XAML page in .NET MAUI (aka EventCallBack?)


I have a ContentPage in a MAUI Blazor Hybrid app with a BlazorWebView (BWV) that displays a basic form component. I understand how to pass parameters to the RootComponent of the BWV so that the Blazor component has access to the info, but I can't figure out how to do the reverse and pass a response from the component to the .xaml.cs code behind file. Essentially I want to do an EventCallBack like a child component would pass info to its parent component in Blazor. I can't seem to find any info about this so any help would be appreciated!

I tried creating an EventCallBack in the Blazor component and binding that to the BWV in the XAML but I can't seem to find the proper way to achieve this.


Solution

  • Your question is not quite clear, but I am gonna assume you are trying to share data/information between your blazor page and your maui page. For this I would use dependency injection and a state container to store and share the data.

    Create a class and add it via dependency injection. (You can also use an interface). The snippet below might help.

    Create your class to hold your data: MySessionValues.cs

    public class MySessionValues
    {
        public string Id { get; set; }
        public string FirstName { get; set; }
        public string Amount { get; set; }
        public DateTime LastLoginTime { get; set; }
    }
    

    Register the class for dependency injection: MauiProgram.cs

        //Register dependency injection for Maui pages bellow:
        builder.Services.AddSingleton<App>();
        //To be used by Maui and Blazor pages
        builder.Services.AddSingleton<MySessionValues>();
    

    Now in yout blazor page, Inject the MySessionValues Class: MyBlazorPage1.razor

    @inject MySessionValues _mySessionValues;
    //get your values from your state class like so.
    <label @bind="_mySessionvalues.FirstName" />
    
    <button class="btn btn-primary" @onclick="SetMyValues">Set My Values</button>
    
    private async void SetMyValues()
        {
    //you can set your values however you want. Typically from an api call
            _mySessionvalues.FirstName = "Dave";
            _mySessionvalues.Amount = "5000.98";
            _mySessionvalues.LastLoginTime = DateTime.Now;
            _mySessionvalues.Id = "12345";
        }
    

    Your state stays the same across pages cos it’s a singleton. On the Maui pages side, dependency injection is started from the root app. So in your app.xaml.cs file, inject your state class into the constructor like so.

    public App(MySessionValues _mySessionValues)
    {
        InitializeComponent();
    
        MainPage = new MainPage();
    }
    

    Then whenever you want to use MySessionValues in any Maui page, simply inject it into the constructor of that page like so: TestMauiPage.xaml.cs

    public TestMauiPage(MySessionValues _mySessionValues)
        {
            InitializeComponent();
            mylabel.Text = _mySessionValues.FirstName;
        }
    

    In you TestMauiPage.xaml: just name the default label so you can reference it from code, or you can use binding. And you should see your values.

     <VerticalStackLayout>
            <Label 
                Text="Welcome to .NET MAUI!"
                x:Name="mylabel"
                TextColor="Black"
                VerticalOptions="Center" 
                HorizontalOptions="Center" />
        </VerticalStackLayout>
    

    Remember whenever you are calling the Maui page, you have to pass it a MySessionValues as the constructor is no longer parameterless. Eg.

    App.Current.MainPage.Navigation.PushModalAsync(new MyMauiPages.TestMauiPage(_mySessionvalues));
    

    Note: in your app.xaml.cs file, it also a good idea to inject _mySessionValues into MainPage, so your state is available to your root maui page(s).

    public App(MySessionValues _mySessionValues)
        {
            InitializeComponent();
    
            MainPage = new MainPage(_mySessionValues);
        }
    

    Should you need to display Maui page and Razor Page side by side and have data exchange in real time, then you will need to subscribe to a Notification event in your class.