我正在WPF中構建一個程序,該程序必須具有多語言支持,並且能夠在運行時切換語言。我的問題涉及本地化的圖像部分。將圖片本地圖片WPF
我已經構建了一個解決方案,它不能以我希望它能工作的方式工作,我希望能解決這些問題。下面發佈的代碼僅僅是我試圖實現的概念的一個演示。我的真實程序有很多圖片,所以我想避免將它們全部放入列表中,逐一更新它們。
我的想法是根據它們所屬的語言來命名圖像。 OriginalSource屬性(缺少更好的名稱)格式化爲「Koala。(lang).jpg」,英語和法語的兩個圖像分別稱爲「Koala.en-GB.jpg」和「Koala.fr-FR .JPG」。
我的問題是沒有在(1)處註釋的代碼,圖像將不會被分配一個「真正的」源(在Image類中)。 (1)處的代碼(這違反了我希望不使用所有圖像的枚舉)之後,在(2)點擊按鈕時,「真實」源不會被更新(012)。我的希望是(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數據類型是因爲我需要在我的真實程序中爲我的圖像和文本(來自XML文件)提供「兩個datacontexts」。
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();
}
}
}
當你某人的評論作出迴應,你應該把下面他們的評論,使它們notofied。 – NVM 2010-08-24 21:15:34
我明白了。好的。感謝您的幫助伴侶。僅供參考,我不得不選擇multibind解決方案,以便能夠將ConverterParameter綁定到來自外部設置文件的值。 – 2010-08-25 06:32:16
沒問題!很長時間以來一直在瘙癢,所以很高興能夠在這裏和那裏給出一些有用的答案。乾杯! – NVM 2010-08-27 01:41:53