it-swarm.com.de

Rufen Sie Werte aus * .resx-Dateien in XAML ab

Ist es möglich, einen Wert aus der Ressourcendatei direkt in das XAML-Markup einzufügen? Oder für die Lokalisierung müssen wir immer etwas in der * .cs-Datei machen:

txtMessage.Text = Messages.WarningUserMessage;

Dabei ist Messages eine Ressource und txtMessage TextBlock.

61
0x49D1

Stellen Sie sicher, dass die Codegenerierung im Resx-Editor auf "Öffentlich" gesetzt ist.

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

Es ist viel einfacher, es so zu machen. Fügen Sie in der XAML-Datei ein xmlns hinzu und verwenden Sie die Ressourcen direkt.

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

Ich verstehe, dass meine Antwort etwas spät ist, aber ich dachte, es lohnt sich zu teilen:

So verwenden Sie eine in der * .resx-Datei gespeicherte Zeichenfolge ohne statisches Schlüsselwort:

  1. Fügen Sie in der App.Xaml-Datei einen Namespace für Eigenschaften xmlns:resource="clr-namespace:YourProject.Properties" hinzu.
  2. Fügen Sie in ApplicationResources (app.xaml-Datei) eine Ressource für Ihre * .resx-Datei hinzu

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

  3. Verwenden Sie in Ihrer XAML-Datei die folgende Bindung, nehmen wir ein Beispiel für den Fenstertitel

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

    TitleString ist der Name von StringProperty in Ihrer * .resx-Datei

  4. Vergessen Sie nicht, den Modifikator für den Zugriff auf die Ressourcendatei in "Öffentlich" zu ändern. 

8
Yogs

Am einfachsten ist es wahrscheinlich, die Elemente direkt zu referenzieren (dies sind standardmäßig statische Eigenschaften):

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

Wenn Sie jedoch an einer lokalisierten WPF-App arbeiten, empfehle ich einen Blick auf die Anleitung zu CodePlex unter http://wpflocalization.codeplex.com/ . Wenn Sie eine Composite-App erstellen (mit PRISM oder MEF), dann habe ich einen Blogbeitrag über einen schönen Weg, um die WPF-Lokalisierung unter Verwendung von Standardbindungen durchzuführen .

5
Steven Robbins

Nach einer ganztägigen Untersuchung dieses Kommentars Xaml-Lokalisierung: Verwenden von .resx-Ressourcen in Xaml ohne x: static habe ich eine einfache Lösung gefunden, um mehrsprachige Unterstützung mit * .resx-Dateien (eingebettete Ressourcen oder referenzierte Assembly) bereitzustellen. Seit Framework 4 gibt es eine Basisklasse namens DynamicObject zum Angeben des dynamischen Verhaltens zur Laufzeit im Namespace System.Dynamic.

Ich habe folgenden ResourceLoader von der System.Dynamic.DynamicObject-Klasse abgeleitet:

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
}

Sie können eine Instanz innerhalb von xaml folgendermaßen erstellen:

<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 # -Code:

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

Es ist jetzt möglich, Zeichenfolgen und Bilder zu binden (Bilder werden in WPF-Compilant BitmapSource konvertiert:

    <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

Der einfachste Weg, auf dem Sie die Breite der Textbox auch entsprechend der Textlänge in jeder Sprache definieren können.

Xaml-Code 

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

Schauen Sie sich die Ressourcendatei an: - Klicken Sie auf Ansicht

0
Vikrant Singh