如何将ResourceDictionary传递给ViewModelLocator

时间:2010-11-30 08:16:11

标签: wpf mvvm-light

您好我在ViewModelLocator中创建了一个属性,以允许ResourceDictionary传递给ViewModelLocator。在我的app.xaml中,我定义了这个:

<vm:ViewModelLocator x:Key="Locator">
  <vm:ViewModelLocator.DefaultUIResourceDictionary>
    <ResourceDictionary Source="Resources/DefaultUIResource.xaml"/>
  </vm:ViewModelLocator.DefaultUIResourceDictionary>
</vm:ViewModelLocator>

它运行正常,但是,当我尝试引用字典时,它有0个项目,我敢肯定DefaultUIResource.xaml有一个项目定义。不确定是什么问题。

另一个问题是,App.Resources属性中定义的资源仅在引用时创建?谁能告诉我App类的生命周期?何时创建了Resources属性中的项目?构造函数之后?

2 个答案:

答案 0 :(得分:1)

相当奇怪的是,问题似乎是你的属性在初始化之前传递了资源字典 - 如果你查看Source setter中字典的DefaultUIResourceDictionary属性,它将是空值。但试试这个:

private ResourceDictionary _defaultUIResourceDictionary;

public ResourceDictionary DefaultUIResourceDictionary
{
    get { return _defaultUIResourceDictionary; }
    set
    {
        _defaultUIResourceDictionary = value;
        Debug.WriteLine(value.Count);
        Dispatcher.CurrentDispatcher.BeginInvoke((Action) delegate
        {
            Debug.WriteLine(value.Count);
            foreach (var item in value)
            {
                Debug.WriteLine(item);
            }
        },
        DispatcherPriority.Background,
        null);
    }
}

您会发现第一个Debug.WriteLine显示的是0 - 与您看到的行为相同。但是在调度程序回调中,计数现在应该是正确的,并且字典的内容可用。 (这就是我在尝试时看到的。)

这可能与您的其他问题有关,也可能与您实际创建资源的时间无关。资源字典通常在WPF中执行延迟资源加载。我说“通常”,因为在某些情况下他们没有。 (例如,如果从未编译的Xaml流加载资源字典。)但在通常情况下 - Resources App属性中的字典,或编译的Xaml中的UI元素中的字典 - 资源请求在你问他们之前不要加载。

这与App类生命周期无关。它不是执行延迟加载的应用程序,而是资源字典本身。它是在每个资源的基础上完成的 - 单个资源在您第一次查找时就会加载。这意味着理论上可以在应用程序生命周期中的任何点加载资源。实际上,一些资源永远不会被加载是很常见的。

这加快了WPF应用程序的启动速度 - 如果您的所有资源在开始时都已加载,则需要的时间比必要时间长。想象一下,您只有在错误情况下才使用的资源,例如 - 您不希望让用户在开始使用您的应用之前等待加载这些资源。

因此,资源字典在编译的Xaml中有时会表现得有些奇怪。你在这里发现的行为绝对是奇怪的。我不确定它实际上是这样的 - 它可能只是资源字典作为特殊情况处理以启用延迟加载这一事实的一些意想不到的后果。

答案 1 :(得分:1)

好的,我找到了解决方案:

我创建了另一个ResourceDictionary,并在其中定义如下:

<ResourceDictionary x:Key="Default" Source="/Resources/DefaultUIResource.xaml"/>

<vm:ViewModelLocator x:Key="Locator" DefaultUIResourceDictionary="{StaticResource Default}"/>

然后在App.Resources中我只使用ResourceDictionary的MergedDictionaries链接到这个新的ResourceDictionary。

相关问题