Как передать ResourceDictionary в ViewModelLocator - PullRequest
1 голос
/ 30 ноября 2010

Привет, я создал свойство в 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 ]

1 голос
/ 30 ноября 2010

хорошо, я нашел решение:

я создал другой ResourceDictionary и определил внутри него следующее:

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

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

, затем в App.Resources я просто использую MergedDictionaries ResourceDictionary для ссылки на этотновый ResourceDictionary.

1 голос
/ 30 ноября 2010

Довольно странно, но проблема в том, что ваше свойство передается в словарь ресурсов перед его инициализацией - если вы посмотрите на свойство Source словаря в вашем установщике 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 - ресурсы не загружаются пока вы не попросите их.

Это не имеет ничего общего с жизненным циклом класса App. Отсроченную загрузку выполняет не приложение, а сам словарь ресурсов. И это делается для каждого ресурса - отдельные ресурсы загружаются при первом их поиске. Это означает, что теоретически ресурсы могут быть загружены в любую точку жизненного цикла приложения. Действительно, некоторые ресурсы обычно не загружаются.

Это ускоряет запуск приложений WPF - если все ваши ресурсы были загружены в начале, это заняло бы намного больше времени, чем необходимо. Например, представьте, что у вас есть ресурсы, используемые только во время ошибок: вы не хотите, чтобы пользователь ждал, пока они загрузятся, прежде чем они смогут начать использовать ваше приложение.

Так что словари ресурсов иногда ведут себя немного странно в скомпилированном Xaml. И поведение, которое вы раскрыли здесь, определенно странно. Я не уверен, что на самом деле так должно быть - это может быть непреднамеренным следствием того факта, что словари ресурсов обрабатываются как особый случай для включения отложенной загрузки.

...