绑定ResourceDictionaries Source属性的正确方法

时间:2013-12-19 11:56:49

标签: c# silverlight xaml mvvm dictionary

我遇到的问题如下,我希望能够在我的silverlight应用程序中进行本地化而不使用通常的资源文件(因为这种方法对我不起作用)。

我支持的每种语言都有几个词典,基本上如下:

Localization.xaml --> for the default language english
Localization.de.xaml --> for german 
Localization.fr.xaml --> for french, I think you get the idea now
.
.
.

现在在app.xaml中定义合并的词典时,我需要能够根据当前的文化动态定义要使用的Localization.xaml。

我知道我可以在app.xaml的代码中执行类似的操作:

private void Application_Startup(object sender, StartupEventArgs e)
{
    this.RootVisual = new MainPage();

    try
    {   ResourceDictionary dict = new ResourceDictionary()
        {
            Source = new Uri("/assembly;component/.../Localizations." + Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName + ".xaml", UriKind.Relative)
        }; 
        Resources.MergedDictionaries.RemoveAt(0);
        Resources.MergedDictionaries.Add(dict);     
    }
    catch(Exception){}
}

然而,有两个问题阻止我使用它。

首先是它在代码背后,因为我使用的是MVVM,我想避免这样做。

其次是我必须使用MergedDictionaries,第0个字典基本上是默认的Localization.xaml。因此,如果我要改变该词典的位置,我必须确保我也在后面的代码中编辑它,这留下了错误的空间。

所以我所做的就是编写一个SourceProvider,它根据当前的文化给出了Uri。

代码如下所示:

public class SourceProvider
{
    public static Uri LocalizationSource
    {
        get
        {
            Uri source = new Uri("assembly;component/.../Localization." + Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName + ".xaml", UriKind.Relative);
            try
            {   
                ResourceDictionary dict = new ResourceDictionary(){Source = source};    
            }
            catch(Exception)
            {
                source = new Uri("/assembly;component/.../Localization.xaml", UriKind.Relative);
            }
            return source;
        }
    }
}

现在在App.xaml中我可以使用如下:

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:ns="clr-namespace:namespace of the sourceprovider"
             x:Class="Peripherie.Configurator.App">
    <Application.Resources>
        <ResourceDictionary>
            <ns:SourceProvider x:Key="Sourcer"/>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="{Binding LocalizationSource, Source={StaticResource Sourcer}}"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

这一切都很好,我可以基本上使用正确的来源,但是这会给我“价值不落在预期范围内”的错误,这有点烦人。

由于错误也找不到所有使用的StaticResources,所以它会显示实际上并不存在的错误,可能会因为数以千计的错误导致错过资源

有没有办法防止这种情况?

0 个答案:

没有答案