in my .NET MAUI MauiProgram.cs, I registered a ResourceManager and also the Code-Behind of my ContentView named MyContentView (which refers to MyContentView.xaml.cs):
Parts from MauiProgram.cs
...
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.UseLocalizationResourceManager(settings =>
{
settings.RestoreLatestCulture(true);
settings.AddResource(AppResources.ResourceManager);
})
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
builder.Services.AddTransient<MyItemInputControlView>();
builder.Services.AddTransient<MyContentPage>();
builder.Services.AddTransient<MyContentPageViewModel>();
MyItemInputControlView.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:views="clr-namespace:MyApp.Pages.Views"
xmlns:loc="clr-namespace:LocalizationResourceManager.Maui;assembly=LocalizationResourceManager.Maui"
xmlns:viewModels="clr-namespace:MyApp.ViewModels"
x:Class="MyApp.Pages.Views.MyItemInputControlView"
x:Name="this">
<StackLayout BindingContext="{x:Reference this}">
<Grid Margin="20, 0, 20, 0">
<Grid.Resources>
<!--<Style TargetType="Entry">
<Setter Property="Padding" Value="2 1" />
<Setter Property="BorderBrush" Value="LightGray" />
</Style>-->
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Grid.Column="0" VerticalOptions="Center">
<Label Text="{Binding NameLabelString}" />
...
</StackLayout>
</Grid>
</StackLayout>
</ContentView>
MyItemInputControlView.xaml.cs (Code-Behind):
namespace MyApp.Pages.Views;
using CommunityToolkit.Maui.Behaviors;
using CommunityToolkit.Mvvm.Messaging;
using LocalizationResourceManager.Maui;
using MyApp.ViewModels;
using MyApp.ViewModels.Messages;
public partial class MyItemInputControlView : ContentView
{
public static readonly BindableProperty NameLabelProperty = BindableProperty.Create(nameof(NameLabelString), typeof(string), typeof(MyItemInputControlView), string.Empty, BindingMode.TwoWay);
public static readonly BindableProperty IsOptionalProperty = BindableProperty.Create(nameof(IsOptionalLabelString), typeof(string), typeof(MyItemInputControlView), string.Empty, BindingMode.TwoWay);
...
private ILocalizationResourceManager localizationResourceManager;
public string NameLabelString
{
get => (string)GetValue(NameLabelProperty);
set => SetValue(NameLabelProperty, $"{localizationResourceManager[value]}:");
}
...
// !!!! THE CONSTRUCTOR WITH ONE PARAMETER IS NEVER REACHED (only default-constructor)!!!
// Wanted to assign the ILocalizationResourceManager to the Code-Behind
public MyItemInputControlView(ILocalizationResourceManager res)
{
//WeakReferenceMessenger.Default.Register<LocalizationResourceManagerProviderMessage>(this, HandleLocalizationResourceManagerProviderMessage);
InitializeComponent();
...
}
private void HandleLocalizationResourceManagerProviderMessage(object recipient, LocalizationResourceManagerProviderMessage message)
{
// Assign the ILocalizationResourceManager instance from the message
localizationResourceManager = message.Value;
}
}
ContentPage-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"
xmlns:viewModels="clr-namespace:MyApp.ViewModels"
xmlns:controls="clr-namespace:MyApp.Pages.Views"
xmlns:loc="clr-namespace:LocalizationResourceManager.Maui;assembly=LocalizationResourceManager.Maui"
x:DataType="viewModels:ManageItemViewModel"
x:Class="MyApp.Pages.ManageItem"
Title="{loc:Translate ManageItem_Heading}">
<VerticalStackLayout>
<Label
Text="{loc:Translate ManageItem_HeadingLabel}"
FontAttributes="Bold"
VerticalOptions="Center"
HorizontalOptions="Center"
Padding="20" />
<StackLayout>
<!-- "ManageItem_MandatoryLabelString" is the String from my Resource-File and will be translated in the Property-Getter -->
<controls:MyItemInputControlView NameLabelString="ManageItem_MyProductNameLabel"
IsOptionalLabelString="ManageItem_MandatoryLabelString"
PlaceholderString="ManageItem_MyProductNamePlaceholder"
EntryInput="{Binding MyItem.Name}"
InputValid="{Binding MyItemNameInputValid, Mode=TwoWay}"
x:Name="firstContentView"/>
</StackLayout>
</ContentPage>
In one of my ContentPages, I then reach a Constructor with two parameters:
//!!! IN MY REGISTERED CONTENT PAGE THE CONSTRUCTOR INCLUDING ILocalizationResourceManager PARAMETER IS REACHED !!!
public partial class MyContentPage : ContentPage
{
public MyContentPage(MyContentPageViewModel viewModel, ILocalizationResourceManager localizationResourceManager)
{
InitializeComponent();
BindingContext = viewModel;
}
}
Unfortunately, in my Code-Behind of my ContentView it is always just the default constructor. Why is this and what am I doing wrong here that the ContentPage correctly has 2 Constructor Parameters and my ContentView hasn't?
I made a small demo trying to use binding for BindableProperty, which works fine.
For MyItemInputControlView.xaml, almost the same:
For MyItemInputControlView.cs, create a BindableProperty. Pay attention to the naming convention of it. For more info. you could refer to Create a bindable property
Also you can see I define a OnStringChanged method which will be invoked if NameLabelString changed. And when changed, we will set new value for label text. For more info, you could refer to Detect property changes
Then the ContentPage which consume the ContentView:
For convenient I just set the BindingContext of ContentPage to MainPageViewModel:
And for MainPageViewModel:
Don't forget to register MainPageViewModel in MauiProgram as we use DI for it:
And the NameLabelString could be localized and pass it to the ContentView. Much appreciated if you could have a try.
Update
Also if you don't want to use bindings, simply set
This tutorial made by Gerald Versluis inspire me. You could refer to Translate Your .NET MAUI App with LocalizationResourceManager.Maui