Использовать RESX-файл в приложении WPF с Prism

#c# #wpf #resx

#c# #wpf #resx

Вопрос:

Я работаю над проектом с WPF / Prism. Приложение имеет разные модули, и один из этих модулей может изменять культуру объекта resx. Это работает нормально, и каждый загруженный модуль будет отображать переведенный текст.

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

 public string UserDetailsLabel => Messages.UserDetailsLabel;

<TextBlock Text="{Binding UserDetailsLabel, Mode=OneWay, NotifyOnSourceUpdated=True}"/>
 

Однако я понятия не имею, где сообщить WPF (или Prism), что культура изменилась, и обновить отображаемое значение. Модуль, который изменяет язык, устанавливает Culture свойство on Messages (генерируется в Messages.Designer.cs ).

Есть ли способ уведомить, что значение изменилось?

Ответ №1:

Есть ли способ уведомить, что значение изменилось?

Реализовать INotifyPropertyChanged и вызвать PropertyChanged событие для UserDetailsLabel свойства, связанного с данными.

Это способ уведомить WPF о том, что исходное значение изменилось.

В контексте многомодульного приложения Prism вы могли бы, например, использовать агрегатор событий для создания события, которое обрабатывает каждая модель представления, вызывая PropertyChanged событие для всех связанных с данными свойств, которые необходимо обновить в представлении.

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

1. Я знаю, что именно так это и должно быть сделано, но свойство доступно только для получения, я никогда не устанавливаю UserDetailsLabel . Я не могу вызвать событие при изменении культуры, потому что другой модуль не «знает» это.

2. Вот где появляется агрегатор событий: blog.magnusmontin.net/2014/02/28 /…

3. Спасибо, это намного полезнее. Я переключился с загруженного события на агрегатор событий. Это также действительно полезно для других событий, которые происходят в определенном модуле.

Ответ №2:

Я решил свою проблему, прикрепив Loaded событие в определении UserControl xaml. Затем представление запрашивает мою модель представления для обновления пользовательского интерфейса. Затем модель представления вызывает RaisePropertyChanged(nameof(UserDetailsLabel)) и обновляет представление.

 // UserListView.xaml
<UserControl ... Loaded="UserListView_OnLoaded">...</UserControl>


// UserListView.xaml.cs
private void UserListView_OnLoaded(object sender, RoutedEventArgs e) {
  var dataContext = (IUserListViewModel) DataContext;
  dataContext.RefreshUI();
}


// UserListViewModel.cs
public void RefreshUI() {
  RaisePropertyChanged(nameof(IUserListViewModel));
}
 

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

1. Почему представление должно указывать модели представления на обновление. Должно быть наоборот. Кроме того, этот подход не будет работать, если вы измените язык после загрузки представления.

2. @mm8 пока это работает, и этот модуль не может изменить культуру. Я знаю, что это не идеально, но есть только один модуль, который может изменить культуру, и он обновляет свой собственный вид