web-dev-qa-db-ja.com

XAMLの* .resxファイルから値を取得する

リソースファイルからXAMLマークアップに値を追加することは可能ですか?または、ローカライズのために、*。csファイルで常に次のようなものを作成する必要があります。

txtMessage.Text = Messages.WarningUserMessage;

ここで、Messagesはリソース、txtMessageはTextBlockです。

66
0x49D1

Resxエディターでコード生成がパブリックに設定されていることを確認してから、次のコマンドを使用できます。

<TextBlock Text="{x:Static Messages.WarningUserMessage}" />
75

このようにするのははるかに簡単です。 XAMLファイルにxmlnsを追加し、リソースを直接使用します。

xmlns:resx="clr-namespace:wpfapplicationname.Properties"
Title="{x:Static resx:Resources.name}"
60
Daniex

返信が少し遅れることは理解していますが、共有する価値があると思いました。

Staticキーワードなしで* .resxファイルに保存された文字列を使用するには:

  1. App.Xamlファイルで、プロパティの名前空間を追加しますxmlns:resource="clr-namespace:YourProject.Properties"
  2. ApplicationResources(app.xaml file)で* .resxファイルのリソースを追加します

    <Application.Resources> <resource:ResourceFileName x:Key="ApplicationStringResources" /> </Application.Resources>

  3. XAMLファイルで次のバインディングを使用し、ウィンドウタイトルの例を見てみましょう

    Title="{Binding TitleString, Source={StaticResource ResourceKey=ApplicationStringResources}}"

    TitleStringは、*。resxファイル内のStringPropertyの名前です

  4. 最後になりましたが、リソースファイルアクセス修飾子をPublicに変更することを忘れないでください。

10
Yogs

最も簡単な方法は、おそらくアイテムを直接参照することです(デフォルトでは内部プロパティです):

<TextBlock x:Name="txtMessage" Text="{x:Static MyApp.Properties.Resource.TextString}"/>

ただし、ローカライズされたWPFアプリで作業している場合は、 http://wpflocalization.codeplex.com/ でCodePlexのガイダンスをご覧になることをお勧めします。アプリ(PRISMまたはMEFを使用)があれば、 標準バインディングを使用してWPFローカリゼーションを実現する素敵な方法に関するブログ投稿 があります。

5
Steven Robbins

このコメント Xamlローカライズ:x:staticを使用せずにXamlで.resxリソースを使用する を1日調査した後、(埋め込みリソースまたは参照アセンブリ)* .resx-ファイルで多言語サポートを提供する簡単なソリューションを見つけました。 Framework 4以降、名前空間System.Dynamicで実行時に動的な動作を指定するDynamicObjectと呼ばれる基本クラスがあります。

System.Dynamic.DynamicObject-クラスから次のResourceLoaderを派生させました。

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内にインスタンスを作成できます。

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

文字列と画像をバインドできるようになりました(画像は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>
1
user3318309

最も簡単な方法。各言語のテキストの長さによってもテキストボックスの幅を定義できます。

Xamlコード

<TextBlock x:Uid="Greeting" Text="" />

リソースファイルを見てください:-[表示]をクリックします

0
Vikrant Singh