添加本地化资源,以便在多个项目之间共享

本文关键字:项目 之间 共享 本地化 资源 添加 | 更新日期: 2023-09-27 18:14:01

由于架构设计规范,我有一个应用程序,从ClassLibraries填充其视图。应用程序本身的行为类似于一种Integrator。

现在我需要添加本地化资源,我可以通过添加*.resw文件成功实现它,但只有当控件在应用程序项目中声明时

我真正需要的是能够以某种方式在整个解决方案之间共享这些资源。

然后,关键是能够通过使用本地化资源(最好使用上面解释的结构)来翻译解决方案的任何控件的内容。

例如,我有以下视图,它根据所选语言填充TextBlocks '内容:

<ComboBox x:Name="Languages"
              ItemsSource="{Binding Languages}"
              SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}">
        <i:Interaction.Behaviors>
            <iCore:EventTriggerBehavior EventName="SelectionChanged">
                <iCore:InvokeCommandAction Command="{Binding ChangeLanguage}" />
            </iCore:EventTriggerBehavior>
        </i:Interaction.Behaviors>
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding LanguageName}" />
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    <TextBlock Text="{Binding Model.HelloText}" FontSize="50" Foreground="Red"/>
    <TextBlock Text="{Binding Model.HowAreYouText}" FontSize="50" Foreground="Red"/>
    <BFview:BFView />
</StackPanel>

其中BFView是存储在另一个项目中的视图(也有两个虚拟文本块)

该视图的Model:

public class MainModel : TranslatableStrings
    {
        private string helloText, howareuText;
        public string HelloText
        {
            get { return this.helloText; }
            set { SetProperty(ref this.helloText, value); }
        }
        public string HowAreYouText
        {
            get { return this.howareuText; }
            set { SetProperty(ref this.howareuText, value); }
        }
    }

Model的基类只是一个契约类,因为它没有实现,而是一个基类型:

public abstract class TranslatableStrings : BindableBase { }

View数据上下文为:

public class MainViewModel : BaseViewModel
    {
        private ObservableCollection<MainViewListRscs> languages = new ObservableCollection<MainViewListRscs>();
        private ICommand changeLang;
        private MainModel model = new MainModel();
        public MainViewModel()
        {
            Languages = new ObservableCollection<MainViewListRscs>()
            {
                new MainViewListRscs { LanguageCode = "es-ES", LanguageName = "Español" },
                new MainViewListRscs { LanguageCode = "en-EN", LanguageName = "English" },
                new MainViewListRscs { LanguageCode = "fr-FR", LanguageName = "Français" },
                new MainViewListRscs { LanguageCode = "de-DE", LanguageName = "Deutsch" }
            };
        }
        public ICommand ChangeLanguage
        {
            get { return changeLang = changeLang ?? new DelegateCommand(OnChangeLanguageRequested); }
        }
        public ObservableCollection<MainViewListRscs> Languages
        {
            get { return this.languages; }
            set
            {
                this.languages = value;
                OnPropertyChanged();
            }
        }
        public MainViewListRscs SelectedLanguage { get; set; }
        public MainModel Model
        {
            get { return this.model; }
            set { this.model = value; }
        }
        private void OnChangeLanguageRequested()
        {
            Logger.Debug("MAINVIEW", SelectedLanguage.LanguageName + " selected.");
            TranslateManager.UpdateStrings<TranslatableStrings>(SelectedLanguage.LanguageCode, this.Model);
        }
        public override Task OnNavigatedFrom(NavigationEventArgs args)
        {
            return null;
        }
        public override Task OnNavigatedTo(NavigationEventArgs args)
        {
            return null;
        }
    }

TranslateManager:

public class TranslateManager
    {
        public async static void UpdateStrings<T>(string langCode, T instance) where T : TranslatableStrings
        {
            //Get all the classes that implement TranslatableStrings
            var currentAssembly = instance.GetType().GetTypeInfo().Assembly;
            var translatableClasses = currentAssembly.DefinedTypes.Where(type => type.BaseType == typeof(T)).ToList();
            //Open RESX file
            ResourceLoader resx = ResourceLoader.GetForCurrentView(langCode);
            foreach(var Class in translatableClasses)
            {
                foreach(var property in Class.DeclaredProperties)
                {
                    string value = resx.GetString(property.Name);
                    var vmProp = instance.GetType().GetTypeInfo().GetDeclaredProperty(property.Name);
                    vmProp.SetValue(instance, value);
                }
            }
        }
    }

我已经实现了改变MainView的两个TextBlocks,但不是另一个项目中的视图。我需要做的是获得一个解决方案中包含的程序集列表。我想,得到只是这将使一切工作,因为我使用的是通用实现。

任何建议都将非常感谢。

谢谢!

添加本地化资源,以便在多个项目之间共享

您的翻译文件作为资源加载。所以你可以在任何地方访问它们,甚至在其他项目中通过

private ResourceLoader _resourceLoader = new ResourceLoader();
var someTranslation =_resourceLoader.GetString("your_localization_key");

将这段代码很好地封装到一个库中,这样您就可以从任何地方轻松地访问它,就这样了!