Programing

XAML의 * .resx 파일에서 값 가져 오기

lottogame 2020. 11. 14. 09:45
반응형

XAML의 * .resx 파일에서 값 가져 오기


리소스 파일의 일부 값을 XAML 태그에 바로 추가 할 수 있습니까? 또는 현지화를 위해 항상 * .cs 파일에서 다음과 같이 만들어야합니다.

txtMessage.Text = Messages.WarningUserMessage;

Messages리소스는 어디에 있고 txtMessageTextBlock입니다.


resx 편집기에서 Code Generation이 Public으로 설정되어 있는지 확인하고 다음을 사용하면됩니다.

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

이렇게하는 것이 훨씬 쉽습니다. XAML 파일에 xmlns를 추가하고 리소스를 직접 사용합니다.

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

내 답장이 조금 늦었 음을 이해하지만 공유 할 가치가 있다고 생각했습니다.

* .resx 파일에 저장된 문자열을 Static 키워드없이 사용하려면 :

  1. App.Xaml 파일에서 속성에 대한 네임 스페이스를 추가합니다. xmlns:resource="clr-namespace:YourProject.Properties"
  2. ApplicationResources (app.xaml 파일)에서 * .resx 파일에 대한 리소스 추가

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

  3. XAML 파일에서 다음 바인딩을 사용하고 창 제목의 예를 살펴 보겠습니다.

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

    TitleString은 * .resx 파일에있는 StringProperty의 이름입니다.

  4. 마지막으로 리소스 파일 액세스 수정자를 공용으로 변경하는 것을 잊지 마십시오.


가장 간단한 방법은 항목을 직접 참조하는 것입니다 (기본적으로 내부 속성 인 정적 속성).

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

지역화 된 WPF 앱에서 작업하는 경우 http://wpflocalization.codeplex.com/ 에서 CodePlex에 대한 지침을 살펴보고 복합 앱을 빌드하는 경우 (PRISM 또는 MEF 사용) 그런 다음 표준 바인딩을 사용하여 WPF 지역화를 수행하는 좋은 방법에 대한 블로그 게시물이 있습니다.


하루 종일 조사한 후이 Comment Xaml 지역화 : Xaml에서 x : static없이 .resx 리소스 사용 (포함 된 리소스 또는 참조 된 어셈블리) * .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>

가장 간단한 방법은 각 언어의 텍스트 길이에 따라 텍스트 상자의 너비를 정의 할 수 있습니다.

Xaml 코드

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

리소스 파일보기 :-보기를 클릭합니다.


Hide an other textblock and bind it's text In that textblock you'll have the resource from .cs

참고URL : https://stackoverflow.com/questions/2919367/get-values-from-resx-files-in-xaml

반응형