Search code examples
winformsblazorblazor-hybrid

Adding a callback to a blazor hybrid in Windows Forms


I´m testing some functionality for seeing the possibilities of Blazor hosted inside a Windows Form application. The solution is the one in the documentation, the classic counter. Now i´m trying to exchange data between the windows and the blazor app, and it works based on this article: How to interact BlazorWebView and Windows Forms

Specifically if i call this:

blazorWebView1.RootComponents.Add<Counter>("#app", new Dictionary<string, object> { { "dummy", "222" } });

I can see the parameter inside the component and use its value.

But i have not been able to use a callback fired inside the component and intercepted in the main form.

This is the callback declaration

 [Parameter]

    public EventCallback Callback { get; set; }

And in the Windows Form

 public async Task DoSomething()
        {
            //anything here
        }

And the passing of the method to the component

blazorWebView1.RootComponents.Add<Counter>("#app", new Dictionary<string, object> { { "Callback",()=> DoSomething() } });

I have used several variations of the same thing but always get an error. In this case

Unable to cast object of type 'System.Func`1[System.Threading.Tasks.Task]' to type 'Microsoft.AspNetCore.Components.EventCallback'.


Solution

  • EventCallback

    If you defined the parameter of type EventCallback:

    private async void IncrementCount()
    {
        currentCount++;
        await Callback.InvokeAsync();
    }
    
    [Parameter]
    public EventCallback Callback { get; set; }
    

    Then you can pass it like this:

    blazorWebView1.RootComponents.Add<Counter>("#app",
        new Dictionary<string, object?>
        {
            {"Callback", new EventCallback(null, ()=>{ MessageBox.Show("Hi"); }) }
        });
    

    Action

    If you defined a parameter of type of Action:

    private void IncrementCount()
    {
        currentCount++;
        Callback?.Invoke();
    }
    
    [Parameter]
    public Action Callback { get; set; }
    

    Then you can pass it like this:

    blazorWebView1.RootComponents.Add<Counter>("#app",
        new Dictionary<string, object?>
        {
            {"Callback", ()=>{ MessageBox.Show("Hi"); } }
        });