Добавьте ресурсы локализации для совместного использования в нескольких проектах

#c# #xaml #windows-phone-8.1

#c# #xaml #windows-phone-8.1

Вопрос:

Из-за спецификаций проектирования архитектуры у меня есть приложение, которое заполняет свои представления из ClassLibraries . Само приложение ведет себя как своего рода интегратор.

Теперь мне нужно добавить ресурсы локализации, и я могу успешно достичь этого, добавив *.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);
                }
            }

        }

    }
  

Я добился изменения двух TextBlocks из MainView , но не представления в другом проекте. Что мне нужно было бы сделать, так это получить список сборок, содержащихся в решении. Я думаю, что получение только этого заставило бы все работать, поскольку я использую общую реализацию.

Любое предложение будет высоко оценено.

Спасибо!

Ответ №1:

Ваши файлы перевода загружаются как ресурсы. Таким образом, вы можете получить к ним доступ в любом месте, даже в других проектах, выполнив что-то вроде

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

Красиво оберните этот код в библиотеку, чтобы у вас был легкий доступ к нему отовсюду, и готово!

Комментарии:

1. Спасибо за ответ! Я работал над решением, реализующим перевод так, как вы мне предложили, но теперь я думаю, что у меня есть ментальный блок… Смотрите обновленный вопрос