mvvmwinui-3winuiwindows-app-sdkcommunity-toolkit-mvvm

How to localize Data Annotation validation error messages in a WinUI3 MVVM application?


I'm building a WinUI3 application using the MVVM Toolkit with [ObservableProperty] and ObservableValidator. I'm using Data Annotations like [Required], [MinLength], [MaxLength] to validate my properties.

I want to localize the validation error messages using .resw resource files. so that when the application language changes, the validation messages are automatically shown in the correct language.

Here is a simplified example from my ViewModel:

public partial class MyViewModel: ObservableValidator
{
    [ObservableProperty]
    [Required(ErrorMessage = "First name is required!")]
    [MinLength(3, ErrorMessage = "First name should be minimum 3 characters!")]
    [MaxLength(100, ErrorMessage = "First name should be maximum 100 characters!")]
    public partial string? FirstName { get; set; }
}

❓ What I want to achieve:

When I change the application language, the ErrorMessage for each validation attribute should be localized using .resw strings or any other method.


❓ My questions:

  1. How can I use .resw localization with ErrorMessage, or is there a workaround for WinUI3?
  2. Can ErrorMessageResourceType and ErrorMessageResourceName work with .resw files in WinUI3?
  3. What's the best practice to handle validation localization in WinUI3 apps using MVVM Toolkit?

🔧 Environment:

Any guidance or examples would be appreciated. Thanks!



Solution

  • To implement localization, check:

    Now let me show you an example with the ObservableValidator:

    Resources enter image description here

    SomePage.xaml

    <StackPanel Orientation="Horizontal">
        <TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <Button Command="{x:Bind ViewModel.SubmitCommand}" Content="Submit" />
    </StackPanel>
    <TextBlock Text="{x:Bind ViewModel.ErrorMessage, Mode=OneWay}" />
    

    SomePageViewModel.cs

    public partial class SomePageViewModel : ObservableValidator
    {
        [ObservableProperty]
        [Required(ErrorMessage = "NameIsRequiredErrorMessage")]
        public partial string Name { get; set; }
    
        [ObservableProperty]
        public partial string ErrorMessage { get; protected set; } = string.Empty;
    
        [RelayCommand]
        private void Submit()
        {
            ValidateAllProperties();
    
            if (HasErrors)
            {
                string errorMessage = GetErrors()?
                    .FirstOrDefault()?
                    .ErrorMessage ?? "Unknown error";
                var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader();
                string localizedErrorMessage = resourceLoader.GetString(errorMessage);
                ErrorMessage = !string.IsNullOrEmpty(localizedErrorMessage)
                    ? localizedErrorMessage
                    : errorMessage;
            }
        }
    }