Blazor UI Communication with .NET Community Toolkit
There are multiple ways to facilitate communication between components in Blazor. Chris Sainty has a great post here that explains a few ways. Recently, Microsoft released version 8 of the .NET Community Toolkit library which includes an IMessenger
interface that can be used to...exchange messages. There are a couple of other Blazor libraries that do something similar (Blazor.EventAggregator and BlazorComponentBus). The Community Toolkit is supported by Microsoft and has been highly optimized according to this article.
You can utilize this interface to send and receive messages between various Blazor components. Below I have a simple example that shows this. You can view the code via GitHub here.
Create
Create a new Blazor Server App Empty project. You can use this in Blazor WebAssembly as well, but I'll be using Blazor Server for this example.
Configure
- Install the CommunityToolkit.Mvvm package
- Modify
Program.cs
withbuilder.Services.AddScoped<IMessenger, WeakReferenceMessenger>();
This uses the WeakReferenceMessenger which does not require manually unregistering recipients. Registering with a Scoped
lifetime is useful for Blazor Server so that state is not shared between users and separate browser windows/tabs.
- Add the following to _Imports.razor:
@using CommunityToolkit.Mvvm.Messaging;
Index.razor
The Index.Razor
component is below. This component sends the CountModifiedMessage
which will be handled by any components registered for it.
The steps here are:
- Add a
Count
property - Add a button to increment the
Count
state - Create the
IncrementCount
method - Increment
Count
- Add
@inject IMessenger _messenger
- Add
_messenger.Send(new CountModifiedMessage { Count = Count });
toIncrementCount
- Create
CountModifiedMessage.cs
with anint
propertyCount
. This can be created outside of theIndex.razor
component to be referenced by other components.
@page "/"
<Header></Header>
<h3>Index</h3>
<button @onclick="IncrementCount">Increment Count</button>
@Count
@inject IMessenger _messenger
@code {
public int Count { get; set; }
public void IncrementCount()
{
Count++;
_messenger.Send(new CountModifiedMessage { Count = Count });
}
}
Header.razor
The Header.razor
component is below. This component registers a handler for the CountModifiedMessage
.
The steps here are:
- Add a
Count
property - Add
@inject IMessenger _messenger
- Register a recipient/hander for the
CountModifiedMessage
message inOnInitialized
_messenger.Register<CountModifiedMessage>(this, (_, m) => CountModifiedHandler(m));
- Create the handler method
CountModifiedHandler
- Set
Count
to theCountModifiedMessage.Count
property and callStateHasChanged()
- Add this component to
Index.razor
<h3>Header</h3>
@Count
@inject IMessenger _messenger
@code {
public int Count { get; set; }
protected override void OnInitialized()
{
_messenger.Register<CountModifiedMessage>(this, (_, m) => CountModifiedHandler(m));
}
private void CountModifiedHandler(CountModifiedMessage message)
{
Count = message.Count;
StateHasChanged();
}
}