C# 如何从资源中获取字符串以在 xaml 的 WPF 资源部分中分配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/665764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 12:29:58  来源:igfitidea点击:

How to fetch string from resource to assign in WPF Resource section in xaml

c#wpflocalizationxbap

提问by nmdr

I have a XBAP application with the following user control:

我有一个带有以下用户控件的 XBAP 应用程序:

  <UserControl x:Class="XXX.UsersGrid"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="Auto" Width="Auto">

        <UserControl.Resources>
            <DataTemplate x:Key="UpArrowUsers">
                <DockPanel>
                    <TextBlock Text="xxUser" x:Name="upArrowUsersHeader" HorizontalAlignment="Center"></TextBlock>
                    <Path x:Name="arrow" StrokeThickness = "1" Fill= "gray" Data= "M 5,10 L 15,10 L 10,5 L 5,10"/>
                </DockPanel>
            </DataTemplate>
    </UserControl>
    ...

Now I want to fetch the string "xxUser" from a resx file which is embed as resource in the application How do I achieve this?

现在我想从作为资源嵌入到应用程序中的 resx 文件中获取字符串“xxUser”我该如何实现?

采纳答案by Steven

None of those answers are close to what you want. I'd start by reading about Localization in WPF. You'll find that if you are doing localization with WPF you'll want x:Uid defined on every node in your app.

这些答案都不是你想要的。我首先阅读 WPF 中的本地化。您会发现,如果您使用 WPF 进行本地化,您将需要在应用程序的每个节点上定义 x:Uid。

http://msdn.microsoft.com/en-us/library/ms788718.aspx

http://msdn.microsoft.com/en-us/library/ms788718.aspx

回答by Jakob Christensen

I don't know if this can be done directly in XAML but if you write your own wrapper class around ResourceManager and use it instead. Notice that the class inherits from TextBlock:

我不知道这是否可以直接在 XAML 中完成,但是如果您围绕 ResourceManager 编写自己的包装类并使用它。请注意,该类继承自 TextBlock:

public class ResourceContentTextBlock : TextBlock
{
    public string ResourceName 
    {
        set
        {
            this.Text = Properties.Resources.ResourceManager.GetString(value);
        }
    }
}

You can then use ResourceContentTextBlock in your XAML anywhere you would otherwise use a TextBlock:

然后,您可以在 XAML 中使用 TextBlock 的任何地方使用 ResourceContentTextBlock:

<Window x:Class="WpfApplication3.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:client="clr-namespace:WpfApplication3" 
    >
        <client:ResourceContentTextBlock ResourceName="String1" />
</Window>

回答by Josh G

Create a static class that makes the resources available as properties:

创建一个静态类,使资源可用作属性:

public static class Resources
{
   public string Resource
   {
      return Properties.Resources.ResourceManager.GetString("Resource");
   }
}

Then you can bind your TextBox to this:

然后你可以将你的 TextBox 绑定到这个:

<TextBlock Text="{Binding Source={x:Static local:Resources}, Path=Resource}" x:Name="upArrowUsersHeader" HorizontalAlignment="Center"
   xmlns:local="clr-namespace:MY_NAMESPACE;assembly=MY_ASSEMBLY">

回答by Ben

I was able to do it in a program with:

我能够在一个程序中做到这一点:

<TextBlock VerticalAlignment="Center" Margin="3"
           Text="{x:Static prop:Resources.OpenButton}"
           Visibility="{Binding Source={x:Static prop:Settings.Default}, Path=ShowButtonText, Converter={StaticResource BoolToVis}}"></TextBlock>

I also had to include the .Properties namespace in my xaml, like so:

我还必须在我的 xaml 中包含 .Properties 命名空间,如下所示:

xmlns:prop="clr-namespace:MyProjectNamespace.Properties"

This allowed me to not only use the string resources I had defined for my project for globalization, but I was also able to bind (two way) to my application's Settings. This let me very easilyremember the window's position, size, etc. As you can see, use Settings. for settings, and Resources. for resources.

这使我不仅可以使用为全球化项目定义的字符串资源,而且还可以(两种方式)绑定到应用程序的设置。这让我很容易记住窗口的位置、大小等。如您所见,使用设置。用于设置和资源。为资源。

As Steven mentioned, I think the "official" way or the "best" way is to stick x:Uid on everything that you want to globalize, but I didn't and it worked with no problems. I think the x:Uid thing is mostly required if you are using automated tools or breaking the translation task up as you would in a large project. I just did all my own stuff manually in VS, so maybe it was ok.

正如史蒂文所提到的,我认为“官方”方式或“最佳”方式是将 x:Uid 粘贴到您想要全球化的所有内容上,但我没有这样做,并且没有任何问题。我认为如果您使用自动化工具或像在大型项目中那样分解翻译任务,则最需要 x:Uid 东西。我只是在 VS 中手动完成了我自己的所有工作,所以也许没问题。

Ben

回答by Benny Jobigan

Two more additional points that I forgot to mention above in "I was able to do it...":

我在上面“我能够做到……”中忘记提到的另外两点:

  1. You don't have to wrap the Properties.Resources object in your own. You can access it directly, as I have done in my example above. I think wrapping the object is a way to get the same result as I discuss in my 2nd point.
  2. By default, the resource files are built with "ResXFileCodeGenerator". This makes them internal when it generates the code file, so xaml can't access it. You have to change this to "PublicResXFileCodeGenerator", which generates public classes. You can change this by clicking the resource file in the solution explorer and editing the "Custom Tool" property.
  1. 您不必将 Properties.Resources 对象包装在您自己的对象中。您可以直接访问它,就像我在上面的示例中所做的那样。我认为包装对象是一种获得与我在第二点中讨论的结果相同的结果的方法。
  2. 默认情况下,资源文件是使用“ResXFileCodeGenerator”构建的。这使它们在生成代码文件时成为内部文件,因此 xaml 无法访问它。您必须将其更改为“ PublicResXFileCodeGenerator”,它会生成公共类。您可以通过单击解决方案资源管理器中的资源文件并编辑“自定义工具”属性来更改此设置。

(sorry, I couldn't edit my above post because I was a temporary member at that time.)

(对不起,我无法编辑我上面的帖子,因为我当时是临时会员。)

回答by AechoLiu

As Bensaid, and I found an another tutorial. The access modifierof Resources.resxshould be changed from Internalto Public. I failed many times and after changing the access modifierto Public, it does work.

正如所说,我找到了另一个教程。该access modifierResources.resx应该从改变InternalPublic。我失败了很多次,更改为access modifierPublic,它确实有效。