Я создаю программу в WPF, которая должна иметь многоязычную поддержку с возможностью переключения языка во время выполнения.Мой вопрос касается части изображения локализации.
Я создал решение, которое не работает так, как я надеялся, оно будет работать, и мне нужна помощь в устранении этих проблем.Приведенный ниже код является лишь демонстрацией концепции, которую я пытаюсь реализовать.В моей настоящей программе довольно много картинок, поэтому я не хочу помещать их все в список, обновляя их по одному.
Моя идея состоит в том, чтобы называть изображения в соответствии с тем языком, к которому они принадлежат.Свойство OriginalSource (в отсутствие лучшего названия) форматируется как «Koala. (Lang) .jpg», а два изображения для английского и французского языков называются «Koala.en-GB.jpg» и «Koala.fr-FR»..jpg ".
Моя проблема в том, что без кода, который закомментирован в (1), изображениям не будет присвоен" реальный "источник (в классе Image).
Такжепосле использования кода в (1) (что нарушает мое желание не использовать перечисление всех изображений), «реальный» источник не обновляется в (2) при нажатии на кнопку.Я надеялся, что (3) и (4) решат эти проблемы, но, очевидно, они не помогут.
Помощь будет высоко ценится.Код следующий:
MainWindow.xaml (неверно)
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="700" Width="525">
<Window.Resources>
<local:LanguageCodeSetter x:Key="CodeSetter" LanguageCodeValue="en-GB" />
</Window.Resources>
<StackPanel>
<local:LocalizedImage x:Name="imgKoala" LanguageCode="{Binding Source={StaticResource CodeSetter}, Path=LanguageCodeValue, Mode=OneWay}" OriginalSource="Koala.(lang).jpg" Height="300" Stretch="Uniform" />
<local:LocalizedImage x:Name="imgPenguins" LanguageCode="{Binding Source={StaticResource CodeSetter}, Path=LanguageCodeValue, Mode=OneWay}" OriginalSource="Penguins.(lang).jpg" Height="300" Stretch="Uniform" />
<Button Content="Don't click here!" Click="Button_Click" />
</StackPanel>
</Window>
MainWindow.xaml.cs (неверно)
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
private string LanguageCodeResource
{
get
{
return ((LanguageCodeSetter)Resources["CodeSetter"]).LanguageCodeValue;
}
set
{
((LanguageCodeSetter)Resources["CodeSetter"]).LanguageCodeValue = value;
}
}
public MainWindow()
{
InitializeComponent();
//(1)
//imgKoala.OriginalSource = imgKoala.OriginalSource;
//imgPenguins.OriginalSource = imgPenguins.OriginalSource;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
LanguageCodeResource = "fr-FR";
//(2)
//imgKoala.LanguageCode = imgKoala.LanguageCode;
//imgPenguins.LanguageCode = imgPenguins.LanguageCode;
}
}
public class LocalizedImage : Image
{
public static readonly DependencyProperty LanguageCodeProperty = DependencyProperty.Register("LanguageCode", typeof(string), typeof(LocalizedImage));
public static readonly DependencyProperty OriginalSourceProperty = DependencyProperty.Register("OriginalSource", typeof(string), typeof(LocalizedImage));
public string LanguageCode
{
get
{
return (string)GetValue(LanguageCodeProperty);
}
set
{
SetValue(LanguageCodeProperty, value);
//(3)
SetValue(SourceProperty, new BitmapImage(new Uri(OriginalSource.Replace("(lang)", value), UriKind.RelativeOrAbsolute)));
}
}
public string OriginalSource
{
get
{
return (string)GetValue(OriginalSourceProperty);
}
set
{
SetValue(OriginalSourceProperty, value);
//(4)
SetValue(SourceProperty, new BitmapImage(new Uri(value.Replace("(lang)", LanguageCode), UriKind.RelativeOrAbsolute)));
}
}
}
public class LanguageCodeSetter : INotifyPropertyChanged
{
private string _languageCode;
public event PropertyChangedEventHandler PropertyChanged;
public string LanguageCodeValue
{
get
{
return _languageCode;
}
set
{
_languageCode = value;
NotifyPropertyChanged("LanguageCodeValue");
}
}
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
}
@ NVM
- Указание на запутанные имена.Я обновил свой код.
- Причина, по которой я использую объект INotifyPropertyChanged, заключается в том, что я хочу, чтобы изменения в одной переменной, а именно в ресурсе CodeSetter, распространялись на все экземпляры LocalizedImage.Причиной этого является то, что я создаю приложение WPF с довольно большим количеством изображений, и я не хочу, чтобы меня заставляли добавлять их все в список с выделенным кодом (таким образом, забывая добавить некоторые изображения и делая будущеерефакторинг приложения более утомительный).При нажатии на кнопку значение «LanguageCode» изменяется во всех случаях LocalizedImage, поэтому часть распространения, похоже, работает.Однако установка «реального» источника в (3) не позволяет.Я также попытался установить для base.Source то же значение (новый BitmapImage (...)), но с тем же результатом.
- Свойство (LanguageCodeResource) предназначено только для краткости в обработчике событий Button_Click.
Может быть, я не в том направлении, чтобы решить эту проблему?Буду признателен за дополнительные отзывы.
@ NVM Вот и все.Большое спасибо!
Для всех, кто хочет, я прилагаю свой правильный код.Несколько громоздкий тип данных DataContext связан с тем, что мне нужны «два dacactextex» для моих изображений и текстов (которые приходят из файла XML) в моей реальной программе.
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Title="MainWindow" Height="700" Width="525">
<Window.Resources>
<local:LocalizedImageSourceConverter x:Key="localizedImageSourceConverter" />
</Window.Resources>
<StackPanel x:Name="layoutRoot">
<Image x:Name="imgKoala" Source="{Binding Path=LanguageCode, Converter={StaticResource localizedImageSourceConverter}, ConverterParameter='Koala.(lang).jpg'}" Height="300" Stretch="Uniform" />
<Image x:Name="imgPenguins" Source="{Binding Path=LanguageCode, Converter={StaticResource localizedImageSourceConverter}, ConverterParameter='Penguins.(lang).jpg'}" Height="300" Stretch="Uniform" />
<Button Content="Don't click here!" Click="Button_Click" />
</StackPanel>
MainWindow.cs.xaml
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
private string LanguageCodeValue
{
set
{
layoutRoot.DataContext = new
{
LanguageCode = value
};
}
}
public MainWindow()
{
InitializeComponent();
LanguageCodeValue = "en-GB";
}
private void Button_Click(object sender, RoutedEventArgs e)
{
LanguageCodeValue = "fr-FR";
}
}
public class LocalizedImageSourceConverter : IValueConverter
{
public object Convert(object values, Type targetType, object parameter, CultureInfo culture)
{
return ((string)parameter).Replace("(lang)", (string)values);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}