#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 пока это работает, и этот модуль не может изменить культуру. Я знаю, что это не идеально, но есть только один модуль, который может изменить культуру, и он обновляет свой собственный вид