Проблема со ссылкой на словарь ресурсов, который содержит объединенный словарь - PullRequest
44 голосов
/ 04 августа 2009

У меня есть библиотека CommonLibraryWpfThemes, в которой есть несколько файлов XAML словаря ресурсов. Файл My Themes / Generic.xml содержит объявление ResourceDictionary.MergedDictionaries, объединяющее все остальные файлы.

Generic.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/BrushDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/TextBlockDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/LabelDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/ButtonDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

В моем проекте приложения у меня есть ссылка на CommonLibraryWpfThemes, и я явно ссылаюсь на Generic.xml в своем файле App.xaml.

App.xaml - FAILS

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
    </Application.Resources>
</Application>

Это не работает. При запуске приложения появляется следующая ошибка:

System.Windows.Markup.XamlParseException occurred
  Message="Cannot find resource named '{_fadedOrangeBrush}'. Resource names are case sensitive.  Error at object 'System.Windows.Setter' in markup file 'CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml' Line 18 Position 13."
  Source="PresentationFramework"
  LineNumber=18
  LinePosition=13

Если я помещаю содержимое Generic.xaml в App.xaml напрямую, все работает нормально:

App.xaml - УСПЕХИ

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/BrushDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/TextBlockDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/LabelDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/ButtonDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Может быть, я поступаю неправильно. Моя цель - упростить ссылки на все ресурсы моей темы из нескольких приложений без необходимости перечисления всех отдельных файлов. Есть ли рекомендуемый способ сделать это? (Примечание: я не пытаюсь переключаться между несколькими темами - у меня есть только одна тема.)

В качестве бонуса было бы неплохо, если бы кто-нибудь мог рассказать мне, как ссылаться на ресурсы во внешней библиотеке, не нарушая конструктор в Visual Studio.

Спасибо.

EDIT:

Я попытался обернуть ResourceDictionary в элемент ResourceDictionary.MergedDictionary, но это также не сработало (я получаю ту же ошибку):

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Ответы [ 5 ]

67 голосов
/ 12 ноября 2010

Ответили на аналогичный вопрос здесь ранее, см. Добавление объединенного словаря в объединенный словарь вопрос.

Это ошибка оптимизации, см. Стиль Microsoft Connect / DefaultStyleKey не найден во внутренних MergedDictionaries :

О создании каждого объекта в XAML, если присутствует стиль по умолчанию (то есть стиль с ключом Type), который стиль должен быть применен. Как вы можете представьте себе, есть несколько производительности оптимизации, чтобы сделать это (подразумевается) ищите легкий вес, насколько это возможно. Один из них то, что мы не заглядываем внутрь Ресурсные словари, если они не помечен как «содержащий по умолчанию» Стили». Есть ошибка: если все ваши стили по умолчанию вложены в объединенные словари трехуровневые (или глубже) верхний словарь не получить помеченный, поэтому поиск пропускает его. Обходной путь заключается в том, чтобы поставить по умолчанию Стиль к чему-то, что-нибудь, в Корневой словарь.

Так что добавление фиктивного стиля в корневой словарь исправляет это. Пример

<Application x:Class="MyApp.App"  
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
    <Application.Resources> 
        <ResourceDictionary> 
            <ResourceDictionary.MergedDictionaries> 
                <ResourceDictionary 
                    Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" /> 
                </ResourceDictionary.MergedDictionaries> 
            <!-- Dummy Style, anything you won't use goes --> 
            <Style TargetType="{x:Type Rectangle}" /> 
        </ResourceDictionary> 
    </Application.Resources> 
</Application>   
12 голосов
/ 19 января 2010

Проверьте ваш конструктор в вызовах App.xaml.cs InitializeComponent () - это то, что объединяет словари ресурсов ...

4 голосов
/ 04 августа 2009

Вы вообще не должны ссылаться на generic.xaml, он имеет встроенную поддержку. Однако это означает, что он предоставляет стиль по умолчанию, который вы не задаете явно. Явно установленные стили / шаблоны должны быть достижимы из словарей с явно указанными ссылками.

(РЕДАКТИРОВАТЬ для ясности)

Единственным исключением является App.xaml, где определенные ресурсы становятся доступными всему приложению, не требуя ссылки на какой-либо конкретный словарь ресурсов. Сам ресурс должен быть доступен по имени.

Причина, по которой это не удается

<Application.Resources>
    <ResourceDictionary
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
</Application.Resources>
Я думаю, что

потому что вы не завернули его в оболочку MergedDictionary, добавив его в объединенные словари. Добавление непосредственно к ресурсам работает только для ресурсов, которые вы объявляете локально, например, сами стили и т. д.

Однако, как я уже говорил, вам не нужно никуда объединять generic.xaml, может быть, вам следует просто изменить кисти и другие ресурсы, используемые вне стилей, и объединить только эти ресурсы в app.xaml.

Также обратите внимание, что стили не обязательно должны быть в generic.xaml для поведения "стиля по умолчанию" - если для него доступен стиль с ключом, равным типу элемента (глобально или в локальных ресурсах), то он будет использовать стиль в качестве стиля по умолчанию. generic.xaml - это просто удобство.

Проверьте этот ответ.

Для других пользовательских кистей и т. Д. Вам необходимо явно ссылаться на эти ресурсы.

Вам также следует проверить содержимое WindowDictionary.xaml, эта ошибка имеет определенный запах.

0 голосов
/ 20 ноября 2012

Я получал эту ошибку в своих модульных тестах, и ответ Криса сверху дал мне подсказку, в которой я нуждался. Основываясь на моем первом испытанном методе, я поставил:

        MyApplication.App app = new MyApplication.App();
        app.InitializeComponent();

И вдруг он может найти мой шаблон для моих страниц. Примечание: это означает, что вы должны проверить, существует ли экземпляр вашего приложения, если вы также тестируете свой App.cs.

0 голосов
/ 15 октября 2010

Мое решение здесь , нажмите Временные решения.

...