从XAML中的* .resx文件获取值
是否有可能从资源文件中添加一些值到XAML标记? 或者对于本地化,我们总是要在* .cs文件中做这样的事情:
txtMessage.Text = Messages.WarningUserMessage;
Messages
是资源, txtMessage
是TextBlock。
确保代码生成在resx编辑器中设置为Public,那么你可以简单地使用:
<TextBlock Text="{x:Static Messages.WarningUserMessage}" />
这样做很容易。 在XAML文件中添加一个xmlns,并直接使用这些资源。
xmlns:resx="clr-namespace:wpfapplicationname.Properties" Title="{x:Static resx:Resources.name}"
我明白我的回复有点晚了,但我认为它值得分享:
要使用存储在不带Static关键字的* .resx文件中的string:
- 在App.Xaml文件中为Properties
xmlns:resource="clr-namespace:YourProject.Properties"
添加一个名称空间xmlns:resource="clr-namespace:YourProject.Properties"
-
在ApplicationResources(app.xaml文件)中为* .resx文件添加一个资源
<Application.Resources> <resource:ResourceFileName x:Key="ApplicationStringResources" /> </Application.Resources>
-
在你的XAML文件中使用下面的绑定,让我们举一个窗口标题的例子
Title="{Binding TitleString, Source={StaticResource ResourceKey=ApplicationStringResources}}"
TitleString是* .resx文件中的StringProperty的名称
-
最后但并非最不重要的是,不要忘记将资源文件访问修饰符更改为Public。
请享用 :)
最简单的方法可能是直接引用这些项目(它们是静态属性,默认为内部):
<TextBlock x:Name="txtMessage" Text="{x:Static MyApp.Properties.Resource.TextString}"/>
如果您正在使用本地化的WPF应用程序,那么我build议您参阅http://wpflocalization.codeplex.com/上的CodePlex指南,如果您要构build复合应用程序(使用PRISM或MEF)那么我有一个很好的方式来完成使用标准绑定WPF本地化的博客文章; 。
经过一整天的调查这个评论Xaml本地化:在xaml中使用.resx资源没有x:static我find了一个简单的解决scheme来提供(embedded式资源或引用程序集)* .resx文件的多语言支持。 自Framework 4起,有一个名为DynamicObject的基类,用于在命名空间System.Dynamic中指定运行时的dynamic行为。
我从System.Dynamic.DynamicObject派生下面的ResourceLoader – class:
public class ResourceLoader : DynamicObject { #region Fields --------------------------------------------------------------- private const string DefaultResourcesSuffix = "Resource"; private ResourceManager _resourceMan; private CultureInfo culture; private readonly string _defaultAssemblyName; private readonly Assembly _defaultAssembly; private Assembly theAssembly; private string resourcesSuffix; private string assembly; #endregion // Fields #region Properties ----------------------------------------------------------- /// <summary> /// Gets or sets the assembly. /// </summary> public string Assembly { get { return assembly; } set { assembly = value; theAssembly = System.Reflection.Assembly.Load(assembly); _resourceMan = null; } } /// <summary> /// Gets or sets the resources suffix. /// </summary> public string ResourcesSuffix { get { return resourcesSuffix; } set { resourcesSuffix = value; _resourceMan = null; } } /// <summary> /// Get, set culture /// </summary> public CultureInfo CurrentCulture { get { this.culture = this.culture ?? CultureInfo.InvariantCulture; return this.culture; } set { this.culture = value; } } /// <summary> /// Creates new instace of <see cref="System.Resources.ResourceManager"/> at initialisation or change of <see cref="ResourceFileAccessSample.ResourceBinding.ResourceLoader.Assembly"/>. /// </summary> private ResourceManager ResourceManager { get { if (ReferenceEquals(_resourceMan, null)) { ResourceManager temp = new ResourceManager( string.Format("{0}.{1}", Assembly ?? _defaultAssemblyName, ResourcesSuffix ?? DefaultResourcesSuffix), theAssembly ?? _defaultAssembly); _resourceMan = temp; } return _resourceMan; } } #endregion // Properties #region Methods -------------------------------------------------------------- private object GetResource(string name, CultureInfo language) { if (language == null || language == CultureInfo.InvariantCulture) return ResourceManager.GetObject(name); return ResourceManager.GetObject(name, language); } /// <summary> /// Provides the implementation for operations that get member values. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as getting a value for a property. /// </summary> /// <param name="binder">Provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the <see cref="T:System.Dynamic.DynamicObject"/> class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies whether the member name is case-sensitive.</param> /// <param name="result">The result of the get operation. For example, if the method is called for a property, you can assign the property value to <paramref name="result"/>.</param> /// <returns> /// true if the operation is successful; otherwise, false. If this method returns false, the run-time binder of the language determines the behavior. (In most cases, a run-time exception is thrown.) /// </returns> public override bool TryGetMember(GetMemberBinder binder, out object result) { result = GetResource(binder.Name, this.culture); if (result != null && result.GetType() == typeof(System.Drawing.Bitmap)) { System.Drawing.Bitmap currentBmp = result as System.Drawing.Bitmap; currentBmp.MakeTransparent(System.Drawing.Color.Magenta); BitmapSource src = Imaging.CreateBitmapSourceFromHBitmap(currentBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); result = src; } return result == null ? false : true; } /// <summary> /// Switch set culture /// </summary> public void SwitchCulture(CultureInfo NewCulture) { this.culture = NewCulture; } #endregion // Methods #region Constructors --------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="ResourceLoader"/> class. /// </summary> public ResourceLoader() : this(CultureInfo.InvariantCulture, DefaultResourcesSuffix) { } /// <summary> /// Initializes a new instance of the <see cref="ResourceLoader"/> class. /// </summary> public ResourceLoader(CultureInfo InitCulture, string ResourceSuffix) { _defaultAssemblyName = GetType().Assembly.GetName().Name; _defaultAssembly = GetType().Assembly; this.culture = InitCulture; this.resourcesSuffix = ResourceSuffix; } #endregion // Constructors }
你可以像这样在xaml中创build实例:
<Application x:Class="ResourceFileAccessSample.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:src="clr-namespace:ResourceFileAccessSample.ResourceBinding" StartupUri="Window1.xaml" Startup="Application_Startup" > <Application.Resources> <src:ResourceLoader x:Key="resource" CurrentCulture="(Default)" ResourcesSuffix="Resource" /> </Application.Resources>
C#代码:
/// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { private ResourceLoader res; public Window1() { InitializeComponent(); // load it from WPF Resources this.res = (ResourceLoader)this.FindResource("resource"); // or create an instance //this.res = new ResourceLoader(CultureInfo.InvariantCulture, "Resource"); this.LayoutRoot.DataContext = res; } private void btnSwichLanguage_Click(object sender, RoutedEventArgs e) { res.SwitchCulture(new CultureInfo("de")); this.LayoutRoot.DataContext = null; this.LayoutRoot.DataContext = res; } }
现在可以绑定string和图像(图像将被转换成WPF编译器BitmapSource:
<StackPanel Name="LayoutRoot" Orientation="Vertical"> <Label Name="lblText" Content="{Binding Path=rsName, Mode=OneWay}" HorizontalContentAlignment="Center" Margin="5" Padding="0" /> <Image Source="{Binding Path=AlignObjectsTop}" Height="16" Width="16" Margin="5" /> <Button Name="btnSwichLanguage" Content="Switch to de" Click="btnSwichLanguage_Click" MinHeight="25" Width="100" /> </StackPanel>
隐藏其他文本块并将其绑定文本在该文本块中,您将拥有来自.cs的资源
最简单的方法,您可以根据每种语言的文本长度来定义文本框的宽度。
Xaml代码
<TextBlock x:Uid="Greeting" Text="" />
资源文件: –
名称 – 值
Greeting.Text – 你好
Greeting.width – 20
看看资源文件: – 点击查看