PersonalApp/
│
├── App.xaml / App.xaml.cs
├── MainPage.xaml / MainPage.xaml.cs
├── MauiProgram.cs
├── Resources/
│ ├── Localization/
│ │ ├── AppResources.resx ← Английский (по умолчанию)
│ │ └── AppResources.ru.resx ← Русский
│
└── Localization/
└── LocalizationResourceManager.cs
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="HelloText" xml:space="preserve">
<value>Hello, world!</value>
</data>
<data name="ButtonText" xml:space="preserve">
<value>Click me</value>
</data>
</root>
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="HelloText" xml:space="preserve">
<value>Привет, мир!</value>
</data>
<data name="ButtonText" xml:space="preserve">
<value>Нажми меня</value>
</data>
</root>
using System.ComponentModel;
using System.Globalization;
using System.Resources;
namespace PersonalApp.Localization;
public class LocalizationResourceManager : INotifyPropertyChanged
{
public static LocalizationResourceManager Instance { get; } = new();
public ResourceManager ResourceManager { get; set; }
public CultureInfo CurrentCulture { get; private set; } = CultureInfo.CurrentUICulture;
public event PropertyChangedEventHandler PropertyChanged;
public string this[string key] => ResourceManager?.GetString(key, CurrentCulture) ?? key;
public void SetCulture(CultureInfo culture)
{
CurrentCulture = culture;
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
// Обновим привязки
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
}
}
using Microsoft.Maui;
using Microsoft.Maui.Hosting;
using PersonalApp.Localization;
using System.Globalization;
using System.Resources;
namespace PersonalApp
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
// Добавляем сервис локализации
builder.Services.AddSingleton(LocalizationResourceManager.Instance);
// Указываем .resx-файл (убедись в правильном пути и namespace)
var resourceManager = new ResourceManager("PersonalApp.Resources.Localization.AppResources", typeof(MauiProgram).Assembly);
LocalizationResourceManager.Instance.ResourceManager = resourceManager;
return builder.Build(); // ← должен быть последним!
}
}
}
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="PersonalApp.MainPage"
Title="Главная">
<VerticalStackLayout Padding="20">
<Label Text="{Binding [HelloText]}"
FontSize="24"
HorizontalOptions="Center" />
<Button Text="{Binding [ButtonText]}"
HorizontalOptions="Center" />
<Button Text="Сменить язык"
Clicked="OnChangeLanguageClicked"
BackgroundColor="#00CFC5"
TextColor="White"
Margin="20,40,20,0"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
using Microsoft.Maui.Controls;
using PersonalApp.Localization;
using System.Globalization;
using System.Diagnostics;
namespace PersonalApp;
public partial class MainPage : ContentPage
{
private string _currentLang = "ru";
public MainPage()
{
InitializeComponent();
// Подключаем ViewModel напрямую к менеджеру локализации
BindingContext = LocalizationResourceManager.Instance;
try
{
LocalizationResourceManager.Instance.SetCulture(new CultureInfo(_currentLang));
}
catch (Exception ex)
{
Console.WriteLine($"[MainPage] Ошибка локализации: {ex}");
}
}
// Переключение языка по нажатию
private void OnChangeLanguageClicked(object sender, EventArgs e)
{
_currentLang = _currentLang == "ru" ? "en" : "ru";
LocalizationResourceManager.Instance.SetCulture(new CultureInfo(_currentLang));
Debug.WriteLine($"Язык переключён на {_currentLang}");
Debug.WriteLine($"HelloText: {LocalizationResourceManager.Instance["HelloText"]}");
Debug.WriteLine($"ButtonText: {LocalizationResourceManager.Instance["ButtonText"]}");
}
}
using PersonalApp.Localization;
using System.Globalization;
namespace PersonalApp
{
public partial class App : Application
{
public App()
{
InitializeComponent();
try
{
LocalizationResourceManager.Instance.SetCulture(new CultureInfo("ru"));
}
catch (Exception ex)
{
Console.WriteLine($"[App.cs] Ошибка локализации: {ex}");
}
MainPage = new MainPage(); // НЕ AppShell — упростим
}
}
}