WPF Централизовать ресурсы xaml/image в многоуровневом/проектном решении

Моя ситуация такова. У меня есть несколько проектов в рамках решения WPF, которые составляют многоуровневое приложение, которое я разрабатываю. Поскольку отдельным проектам иногда потребуется доступ к одному и тому же изображению или ресурсу xaml, я бы хотел централизовать "общедоступные" ресурсы для одного проекта, на который можно ссылаться любые другие проекты, требующие этих "общедоступных" ресурсов. Например, у меня есть изображение BMP, которое я использую в различных элементах управления и окнах в отдельных проектах, которые служат баннером/логотипом. Похоже, я должен добавить этот образ в качестве ресурса в проект публичных ресурсов и ссылаться на него из других моих проектов, вместо того, чтобы добавлять изображение отдельно к каждому его проекту. Если это возможно, как бы это выглядело и как я должен это делать? Если моя идея просто отстой, я открыт для предложений, но проект будет довольно большим, поэтому я не хочу добавлять ресурсы повсюду.

Спасибо!

P.S. Я немного искал эту тему, но есть много ответов на мусор от людей, которые не знают, что они делают. Учитывая, что я относительно новичок в WPF, я предпочел бы получить прямой ответ на мою проблему.

Ответ 1

Ну, после некоторых попыток и исследований я нашел решение своего вопроса. Кажется, что кусочки моего ответа были разбросаны по всему Интернету, поэтому я попытаюсь объяснить все это сразу, в одном месте. Чтобы перекрыть, я в основном хотел централизовать любые ресурсы, используемые в рамках проектов в рамках моего решения. Это шаги, которые я в конце концов выполнил, чтобы выполнить это.

1. Создайте проект User Control в своем решении (любой проект, который может содержать ресурсные словари). Я буду рассматривать этот проект как "ресурсный проект".

2. Добавьте файлы ресурсов (изображения и т.д.), Которые вы хотите разделить между проектами в проект ресурса. Я пытаюсь организовать файлы в подкаталогах, которые имеют смысл. Вам нужно будет установить действие сборки в "Ресурс", чтобы оно скомпилировалось в выходной двоичный файл.

3. Теперь добавьте ресурсный словарь в проект ресурса. В моем случае я хотел ссылаться на несколько изображений, поэтому я сделал один из них под названием "ImageDictionary.xaml".

4. Добавьте ссылки на файлы изображений в словаре ресурсов. Я ссылаюсь на изображения здесь, но это только словарь ресурсов, вы можете помещать туда все. Строка в середине - это только относительный путь к файлу изображения, на который вы ссылаетесь.

<ImageSource x:Key="SomeImageKey"> 
    Images/SomeImage.bmp
</ImageSource>

5. Теперь перейдите к проекту, который требует словарь ресурсов, который вы только что сделали на шаге 4. Это может быть другой пользовательский элемент управления или окно, что угодно. Щелкните правой кнопкой мыши ссылки на проект и добавьте ссылку на проект ресурса.

6. Теперь в текущем проекте нужно ссылаться на словарь, который вы сделали на шаге 4, который определен в проекте ресурса. Сначала я сделал пользовательский контроль, так что мой код будет выглядеть ниже... Обратите внимание, что я использовал объединенные словари. Я планирую использовать более позднее, поэтому я выбрал этот способ вместо одного словаря. "ResourceProject" ниже - название проекта/сборки, к которому вы добавили ресурс. "Компонент" - это ключевое слово, которое должно быть там, за которым следует путь к файлу кода словаря xaml.

<UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/ResourceProjectAssembly;component/Resources/ImageDictionary.xaml" />  
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>        
    </UserControl.Resources>

Как вы можете видеть, ссылка на внешний ресурсный словарь требует чего-то, называемого "URI пакета". Я нашел короткий способ сделать это. Длинный путь довольно уродливый, и, насколько я знаю, нет никакого преимущества. Но вот как выглядит длинный путь.

<UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/ResourceProjectAssembly;component/Resources/ImageDictionary.xaml" />  
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>        
    </UserControl.Resources>

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

<Image Source="{StaticResource SomeImageKey}" />

8. Важная заметка! Это вызвало у меня головную боль некоторое время, прежде чем я ее нашел. Убедитесь, что проект запуска в вашем решении имеет ссылку на проект ресурса EVEN, ЕСЛИ ПРОЕКТ СТАРТОВАНИЯ НЕ ИСПОЛЬЗУЕТ ПРОЕКТ РЕСУРСА. (Например, щелчки правой кнопкой мыши, добавление ссылки и т.д.) Ресурсы не будут скомпилированы в вывод, если вы этого не сделаете. Эта часть была сложной, потому что дизайнер даже показывал мои образы, и у меня не было ошибок xaml, но во время выполнения он бы выбрал свойство set и не смог найти исключения файлов. Это исчезло, когда я ссылался на свой ресурсный проект из моего проекта запуска.

Надеюсь, это помогает кому-то. Ниже приведены некоторые ссылки на несколько мест (включая stackoverflow), которые дали мне то, что мне нужно, чтобы собрать все части.

http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/03/creating-and-consuming-resource-dictionaries-in-wpf-and-silverlight.aspx

Загрузите стили WPF или другие статические ресурсы из внешнего файла или сборки

ResourceDictionary в отдельной сборке