Стили всей сборки / корневого уровня в библиотеке классов WPF - PullRequest
47 голосов
/ 31 декабря 2008

У меня есть сборка библиотеки классов C # (2008 / .NET 3.5), которая поддерживает WPF (на основе этой статьи ).
Я создал несколько окон и сейчас пытаюсь создать общий стиль для них. Однако, поскольку это библиотека классов (а не приложение WPF), у меня нет app.xaml (и содержащегося в нем Application & соответствующим Application.Resources), в котором можно хранить эти стили для глобального доступа.

Итак: Как создать набор определений стилей верхнего уровня, который будет виден всем файлам xaml в сборке, , учитывая, что у меня нет app.xaml (см. выше) ? И / или возможно ли добавить рабочий app.xaml в библиотеку классов?

К вашему сведению, я попытался создать ResourceDictionary в файле ResourceDictionary.xaml и включить его в каждое окно в блоке "Window.Resources". Это оказалось для решения стиля кнопок и т. Д., Но не для окружающего окна. Я могу поместить Style="{StaticResource MyWindowStyle}" в блок открытия окна, и он прекрасно компилируется и отображается в окне VS Design, но во время реального времени выполнения я получаю исключение синтаксического анализа (MyWindowStyle не может быть найден; я предполагаю, что Visual Studio видит словарь включается после рассматриваемой строки, но CRL делает вещи более последовательно и, следовательно, еще не загрузил ResourceDictionary).


Спасибо за идеи, но все равно не пойдет ... по-видимому, библиотека классов НЕ поддерживает неявно generic.xaml. Я добавил generic.xaml в свой проект библиотеки классов и установил для его действия «Resource». Содержит:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Window}" x:Key="MyWindow">
        <Setter Property="Background" Value="Black"/>
    </Style>
</ResourceDictionary>

Окно xaml, которое я хочу использовать в теме, выглядит так:

<Window x:Class="MyAssembly.ConfigureGenericButtons"
    x:ClassModifier="internal"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Style="{StaticResource MyWindow}"
    Title="ConfigureGenericButtons">
...Buttons, etc...
</Window>

Хотя в окне VS Design не отображается окно, использующее стиль MyWindow (т. Е. Черный фон), оно прекрасно компилируется и запускается. Однако когда приложение, содержащее эту библиотеку классов, выполняет вызов, который вызывает отображение этого окна, я получаю исключение XamlParseException:

Не удается найти ресурс с именем '{MyWindow}'.

Я также попытался пропустить параметр Style, чтобы посмотреть, будет ли окно использовать стиль по умолчанию (и я попробовал это как с ключом x: Key в generic.xaml, так и без него). Никаких ошибок, но что-либо определенное в generic.xaml также не показывалось.

Я делаю что-то не так здесь или какие-либо другие идеи о том, как можно разрешить использование общих пользовательских стилей в окне (т. Е. Не нужно определять стили в xaml каждого окна) - с оговоркой, что это НЕ является приложением?

Ответы [ 6 ]

14 голосов
/ 02 января 2009

Попробуйте добавить

Style={DynamicResource MyStyle}

В этом случае вы не можете использовать StaticResource.

13 голосов
/ 01 января 2009

Звучит как работа для тематики.

  1. Добавьте /themes/generic.xaml ResourceDictionary в ваш проект.
  2. Добавьте в AssemblyInfo.cs следующее: [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
  3. Прибыль!

Любые ресурсы, которые вы добавляете в общие, будут использоваться всеми элементами управления. Также вы можете создавать темы для определенного профиля (Luna, Aero и т. Д.), Включив файл ResourceDictionary с правильным именем темы в каталог themes.

Вот ссылка на дополнительную информацию: Создание и применение пользовательских тем

3 голосов
/ 02 января 2009

Если у вас нет app.xaml, вы все равно можете загрузить его в ресурсы уровня приложения, но вам нужно написать код (не xaml), как это ...

void LoadIt()
{
     ResourceDictionary MyResourceDictionary = new ResourceDictionary();
     MyResourceDictionary.Source = new Uri("MyResources.xaml", UriKind.Relative);
     App.Current.Resources.MergedDictionaries.Add(  MyResourceDictionary )
}

проверьте этот сайт для примера: http://ascendedguard.com/2007/08/one-of-nice-features-about-wpf-is-how.html

1 голос
/ 08 октября 2014

Dr. У WPF (или человека, ранее известного как доктор WPF) есть отличная запись на эту тему.

Вот выдержка из поста, в котором они создают объект Application и добавляют ресурсы:

if (Application.Current == null)
{
    // create the Application object
    new Application();

    // merge in your application resources
    Application.Current.Resources.MergedDictionaries.Add(
        Application.LoadComponent(
            new Uri("MyLibrary;component/Resources/MyResourceDictionary.xaml",
            UriKind.Relative)) as ResourceDictionary);
}

Поскольку моя сборка размещается через взаимодействие, мне пришлось добавить следующие настройки ShutdownMode и завершить работу по завершении:

new Application() { ShutdownMode = ShutdownMode.OnExplicitShutdown };

Это сработало как шарм.

0 голосов
/ 17 марта 2017

Итак, потратив много времени, я наконец понял это. Вот как это сделать:

  1. В библиотеке элементов управления WPF добавьте новую папку с именем themes.
  2. Внутри папки themes добавьте словарь ресурсов с именем generic.xaml.
  3. Внутри generic.xaml добавьте свой ресурс, используя следующий синтаксис:

    <SolidColorBrush x:Key="{ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}" Color="Blue" />
    
  4. В вашем контроле используйте следующий синтаксис для доступа к этому ресурсу:

    Background="{StaticResource {ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}}"
    

На что обратить внимание:

  1. Шаг 1 и 2 обычно автоматически выполняются для вас Visual Studio при создании новой библиотеки элементов управления WPF.
  2. Я не до конца понимаю назначение первого параметра ComponentResourceKey, но это необходимо. Используйте имя элемента управления, который будет использовать этот ресурс.
  3. Разработчик Visual Studio не смог найти ресурс в моем случае. Это может быть проблема с кешем, я не уверен. Однако во время выполнения это работает аккуратно.
  4. Подробнее об этом синтаксисе можно прочитать в этой статье MSDN .

Надеюсь, это облегчит жизнь.

0 голосов
/ 01 января 2009

если вы загрузите его в Window.Resource, словарь доступен только для дочерних элементов этого окна. Вы должны иметь это доступным для окна и его детей.

Попробуйте загрузить его в файл app.xaml. Это должно сделать его ресурсом приложения, а не ресурсом окна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...