C# 在WPF中定位图像
我正在用WPF构建一个程序,该程序必须具有多语言支持,并且能够在运行时切换语言。我的问题涉及本地化的图像部分 我已经建立了一个解决方案,它不能像我希望的那样工作,我希望能得到一些帮助来解决这些问题。下面发布的代码只是我试图实现的概念的演示。我真正的程序有很多图片,所以我想避免把它们都放在一个列表中,逐个更新 我的想法是根据图像所属的语言来命名它们。OriginalSource属性(没有更好的名称)的格式为“Koala.(lang).jpg”,英文和法文的两个图像分别称为“Koala.en GB.jpg”和“Koala.fr-fr.jpg” 我的问题是,如果没有在(1)中注释的代码,图像将不会被分配“真实”源(在图像类中) 另外,在使用了(1)处的代码(这违反了我不希望使用所有图像的枚举)之后,在(2)处单击按钮时,不会更新“真实”源。我的希望是(3)和(4)能解决这些问题,但显然不能 非常感谢您的帮助。 代码如下: MainWindow.xaml(不正确) @NVMC# 在WPF中定位图像,c#,.net,wpf,xaml,localization,C#,.net,Wpf,Xaml,Localization,我正在用WPF构建一个程序,该程序必须具有多语言支持,并且能够在运行时切换语言。我的问题涉及本地化的图像部分 我已经建立了一个解决方案,它不能像我希望的那样工作,我希望能得到一些帮助来解决这些问题。下面发布的代码只是我试图实现的概念的演示。我真正的程序有很多图片,所以我想避免把它们都放在一个列表中,逐个更新 我的想法是根据图像所属的语言来命名它们。OriginalSource属性(没有更好的名称)的格式为“Koala.(lang).jpg”,英文和法文的两个图像分别称为“Koala.en GB.
- 关于混淆名字的观点。我已经更新了我的代码
- 我使用INotifyPropertyChanged对象的原因是我希望一个变量(即称为CodeSetter的资源)中的更改传播到LocalizedImage的所有实例。这样做的原因是,我正在构建一个包含大量图像的WPF应用程序,我不想被迫将它们全部添加到代码隐藏的列表中(从而忘记添加一些图像,并使应用程序的未来重构更加繁琐)。点击按钮,“LanguageCode”的值在LocalizedImage的所有实例中都会发生变化,因此传播部分似乎可以工作。但是,将“真实”源设置为(3)并不适用。我还尝试将base.Source设置为相同的值(新的BitmapImage(…),但结果相同
- 属性(LanguageCodeResource)仅用于按钮单击事件处理程序中的简要说明
<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>
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();
}
}
}
首先,你应该停止使用“语言代码”来命名任何东西。这真是令人困惑:D 其次是
<Window.Resources>
<local:LanguageCodeSetter x:Key="LanguageCode" LanguageCode="en-GB" />
</Window.Resources>
应该是依赖项属性,而不是INotify支持的clr属性
编辑
在参考资料部分,我仍然不知道LanguageCode属性如何工作
无论如何,在理解了您在这里要实现的目标后,有一个非常简单的解决方案
<Image Source="{Binding Path=LanguageCode, Converter={StaticResource localizedImageSourceConverter}, ConverterParameter='Koala.jpg'}"/>
public class LocalizedImageSourceConverter : IValueConverter
{
public object Convert(object values, Type targetType, object parameter, CultureInfo culture)
{
string fileName = Path.GetFileNameWithoutExtension((string)parameter);
string extension = Path.GetExtension((string)parameter);
string languageCode = (string)values;
return string.Format("{0}{1}{2}", fileName, languageCode, extension);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
公共类LocalizedImageSourceConverter:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
string fileName=Path.GetFileNameWithoutExtension((字符串)参数);
string extension=Path.GetExtension((string)参数);
字符串语言代码=(字符串)值;
返回string.Format(“{0}{1}{2}”,文件名,语言代码,扩展名);
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
我没有将源属性绑定到文件路径(URI),而是将其绑定到LanguageCode属性。LanguageCode属性应该位于ViewModel或任何要绑定到的datacontext对象中
转换器将以基本图像的路径作为参数,并将其与绑定的LanguageCodeProperty相结合,以提供本地化的路径。而且,由于您绑定到datacontext中的LanguageCode属性,因此每当它发生更改时,所有图像都将自动更新。请注意,不能绑定转换器参数。如果要同时绑定文件路径和语言代码,请使用多重绑定
*代码中可能有语法错误,我只是想传达这个概念。首先,你应该停止使用“LanguageCode”来命名任何东西。这真是令人困惑:D 其次是
<Window.Resources>
<local:LanguageCodeSetter x:Key="LanguageCode" LanguageCode="en-GB" />
</Window.Resources>
应该是依赖项属性,而不是INotify支持的clr属性
编辑
在参考资料部分,我仍然不知道LanguageCode属性如何工作
无论如何,在理解了您在这里要实现的目标后,有一个非常简单的解决方案
<Image Source="{Binding Path=LanguageCode, Converter={StaticResource localizedImageSourceConverter}, ConverterParameter='Koala.jpg'}"/>
public class LocalizedImageSourceConverter : IValueConverter
{
public object Convert(object values, Type targetType, object parameter, CultureInfo culture)
{
string fileName = Path.GetFileNameWithoutExtension((string)parameter);
string extension = Path.GetExtension((string)parameter);
string languageCode = (string)values;
return string.Format("{0}{1}{2}", fileName, languageCode, extension);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
公共类LocalizedImageSourceConverter:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
string fileName=Path.GetFileNameWithoutExtension((字符串)参数);
string extension=Path.GetExtension((string)参数);
字符串语言代码=(字符串)值;
返回string.Format(“{0}{1}{2}”,文件名,语言代码,扩展名);
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
我没有将源属性绑定到文件路径(URI),而是将其绑定到LanguageCode属性。LanguageCode属性应该位于ViewModel或任何要绑定到的datacontext对象中
转换器将以基本图像的路径作为参数,并将其与绑定的LanguageCodeProperty相结合,以提供本地化的路径。而且,由于您在datacontext中绑定到LanguageCode属性,因此每当它发生更改时,所有图像都将被删除
<Image Source="{Binding Path=LanguageCode, Converter={StaticResource localizedImageSourceConverter}, ConverterParameter='Koala.jpg'}"/>
public class LocalizedImageSourceConverter : IValueConverter
{
public object Convert(object values, Type targetType, object parameter, CultureInfo culture)
{
string fileName = Path.GetFileNameWithoutExtension((string)parameter);
string extension = Path.GetExtension((string)parameter);
string languageCode = (string)values;
return string.Format("{0}{1}{2}", fileName, languageCode, extension);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}