如何强制XAML资源不被延迟(延迟加载)

时间:2014-10-06 08:10:55

标签: wpf internationalization resharper resourcedictionary

通常,XAML资源在被引用之前不会被实例化,例如

<ObjectDataProvider x:Key="T9N" ObjectType="{x:Type properties:Resources}"/>
<c:RegisterI18N x:Key="T9Nx" Source="{StaticResource T9N}"/>

以上是在资源字典中。向全局文化管理器注册ObjectDataProvider T9N 以提供运行时i18n是一种破解。

我们

<Button Command="{Binding RestartCommand}"
        Content="{Binding restart, Source={StaticResource T9N}}" />

但是,除非我们将XAML中的密钥 T9Nx 作为静态资源引用,否则 RegisterI18n 永远不会被实例化。

现在我查看了ResourceDictionary源代码。

http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/ResourceDictionary.cs

并且提示延迟和非延迟内容之间存在差异。

问题是: XAML中是否有办法强制立即实例化元素?

请不要建议做i18n的替代方案。这是关于延迟内容加载的问题。我们已经调查了所有当前动态i18n解决方案,并且没有一个 resharper 兼容。 ObjectDataProvider 似乎与 resharper 一起使用,但是我们需要在管理器创建时注册每个实例,以便我们可以调用 Refresh()方法他们对文化的改变。子类化很明显,但即使运行时行为正确,resharper也无法识别sublcass。

2 个答案:

答案 0 :(得分:0)

执行此操作的一种方法是迭代应用程序的OnStartup中的资源。

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        WalkDictionary(this.Resources);

        base.OnStartup(e);
    }

    private static void WalkDictionary(ResourceDictionary resources)
    {
        foreach (DictionaryEntry entry in resources)
        {
        }

        foreach (ResourceDictionary rd in resources.MergedDictionaries)
            WalkDictionary(rd);
    }
}

参考: http://social.msdn.microsoft.com/Forums/vstudio/en-US/b97a5f83-5394-430e-9a78-9d3a957e3537/dynamicresourcestaticresource-cause-memory-leaks?forum=wpf

答案 1 :(得分:0)

我们现在使用稍微不同的方法,到目前为止效果很好(https://github.com/Weingartner/I18N.Reactive) 基本上,我们实现了CustomTool(?)作为默认ResXFileCodeGenerator的替代方法。 自定义工具使用T4模板生成一个类,该类将resx键公开为属性。 每当您编辑resx文件以便它自动更新时,该工具就会运行。