web-dev-qa-db-ja.com

xamlのWPFリソースセクションで割り当てるリソースから文字列をフェッチする方法

次のユーザーコントロールを備えた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>
    ...

ここで、アプリケーションにリソースとして埋め込まれているresxファイルから文字列「xxUser」をフェッチしたいと思います。これを実現するにはどうすればよいですか。

12
nmdr

それらの答えのどれもあなたが望むものに近いものではありません。まず、WPFでのローカリゼーションについて読みます。 WPFを使用してローカリゼーションを行う場合は、アプリのすべてのノードでx:Uidを定義する必要があることがわかります。

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

4
Steven

私は次のプログラムでそれを行うことができました:

<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>

また、次のように、xamlに.Properties名前空間を含める必要がありました。

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

これにより、グローバリゼーションのためにプロジェクト用に定義した文字列リソースを使用できるだけでなく、アプリケーションの設定に(双方向で)バインドすることもできました。これにより、非常に簡単にウィンドウの位置やサイズなどを覚えておくことができます。ご覧のとおり、[設定]を使用してください。設定、およびリソース。リソース用。

Stevenが述べたように、「公式」または「最良」の方法は、グローバル化したいすべてのものにx:Uidを固定することだと思いますが、私はそうしませんでした。大規模なプロジェクトのように自動化されたツールを使用している場合や翻訳タスクを分割している場合は、x:Uidが主に必要になると思います。 VSで自分のすべての作業を手動で行ったので、おそらく問題ありませんでした。

ベン

45
Ben

上記の「私はそれを行うことができました...」で言及するのを忘れたもう2つの追加のポイント:

  1. Properties.Resourcesオブジェクトを独自にラップする必要はありません。上記の例で行ったように、直接アクセスできます。オブジェクトをラップすることは、2番目のポイントで説明したのと同じ結果を得る方法だと思います。
  2. デフォルトでは、リソースファイルは「ResXFileCodeGenerator」で作成されます。これにより、コードファイルを生成するときにそれらが内部になり、xamlはそれにアクセスできなくなります。これを "PublicResXFileCodeGenerator"に変更する必要があります。これにより、パブリッククラスが生成されます。これを変更するには、ソリューションエクスプローラーでリソースファイルをクリックし、[カスタムツール]プロパティを編集します。

(申し訳ありませんが、当時は一時的なメンバーだったため、上記の投稿を編集できませんでした。)

9
Benny Jobigan

リソースをプロパティとして使用できるようにする静的クラスを作成します。

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

次に、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">
6
Josh G

Ben が言ったように、私は 別のチュートリアル を見つけました。 access modifierResources.resxInternalからPublicに変更する必要があります。何度も失敗し、access modifierPublicに変更した後、機能します。

6
AechoLiu

これをXAMLで直接実行できるかどうかはわかりませんが、ResourceManagerの周りに独自のラッパークラスを記述して、代わりに使用するかどうかはわかりません。クラスがTextBlockから継承していることに注意してください。

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

その後、TextBlockを使用する場所であればどこでもXAMLで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>
1