WPF本地化扩展MVVM绑定

时间:2017-05-15 17:56:39

标签: wpf localization

我正在尝试绑定在ViewModel中声明的名为[" SampleName"]的属性。这里SampleName是关键。但是,在尝试下面的代码时,它会显示为空。

<TextBlock FontSize="14" Text="{lex:BLoc Value=SampleName}" lex:ResxLocalizationProvider.DefaultAssembly="SAS.Resources" lex:ResxLocalizationProvider.DefaultDictionary="Report" HorizontalAlignment="Center" VerticalAlignment="Top" TextDecorations="Underline" FontWeight="DemiBold" Grid.Row="0" Grid.ColumnSpan="{Binding Path=SpanCount}" Grid.Column="0"/>

请建议我。

2 个答案:

答案 0 :(得分:1)

我检查了源代码,并不认为BLoc是这样做的。但我找到了归档相同结果的其他方法。

基于this回答,我提出了这个解决方案。而不是给视图提供资源键,而是给出资源值。如果文化发生变化,那么价值也会发生变化。这是核心实施:

public class MyViewModel : INotifyPropertyChanged {

    public MyViewModel()
    {
        // Properties.Resources is my Resources.resx file and String1 is my resource key
        BindPropertyToResource(nameof(Name), nameof(Properties.Resources.String1));
    }


    private string _name;
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged();
            }
        }
    }

    protected void BindPropertyToResource(string propertyName, string resourceKey){
        WPFLocalizeExtension.Providers.ResxLocalizationProvider resxLocalizationProvider
            = WPFLocalizeExtension.Providers.ResxLocalizationProvider.Instance;

        WPFLocalizeExtension.Providers.ResxLocalizationProvider.SetDefaultAssembly(resxLocalizationProvider, System.Reflection.Assembly.GetCallingAssembly().GetName().Name);
        WPFLocalizeExtension.Providers.ResxLocalizationProvider.SetDefaultDictionary(resxLocalizationProvider, nameof(Properties.Resources));

        var targetProperty = this.GetType().GetProperty(propertyName);
        var locBinding = new WPFLocalizeExtension.Extensions.LocTextExtension(resourceKey);

        locBinding.SetBinding(this, targetProperty);
    }


    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion // INotifyPropertyChanged Members
}

希望这种解决方法能够解决您的问题。

答案 1 :(得分:1)

我使用的是消化的答案,但这并非100%稳定且线程安全。现在我正在使用这个解决方案。

我的观点:

xmlns:lex="http://wpflocalizeextension.codeplex.com"

<TextBlock Text="{Binding ElementName=LocProxy, Path=Result}"/>
<lex:LocProxy Name="LocProxy"
           Source="{Binding NameOfResourceKey}"/>

MyViewModel:

public string NameOfResourceKey { get; set; }

然后像这样设置它为ViewModel:

// Use your way to access classis Resources.resx file
NameOfResourceKey = nameof(Properties.Resources.YourLocalizedMessageKey);
// Use your function to RaiseProperty     
RaisePropertyChanged(nameof(NameOfResourceKey)); 

因此,您需要通过nameof引用资源文件中的资源,将其设置为lex:LocProxy的源,然后绑定到LoxProxy Result,无论您需要本地化字符串。非常简单,然后GUI是handlig所有的本地化,这是最佳的。

对于Raise属性,您可以使用bruno.almeida(OnPropertyChanged)中的函数,或者使用示例MVVMLight nuget包并像我一样在ViewModel中继承ViewModelBase。