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

StackOverflow https://stackoverflow.com/questions/404019

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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


Спасибо за идеи, но все равно ничего не получается...очевидно, что библиотека классов НЕ поддерживает неявное использование generic.xaml.Я добавил generic.xaml в свой проект библиотеки классов и установил для его действия сборки значение "Ресурс".Он содержит:

<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: в generic.xaml, так и без него).Ошибок нет, но все, что определено в generic.xaml, также не появилось.

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

Это было полезно?

Решение

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

Style={DynamicResource MyStyle}

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

Другие советы

Это звучит как работа по тематизации.

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

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

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

Если у вас нет 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

ДокторWPF (или человек, ранее известный как Dr .WPF) обладает отличным Публикация по этому вопросу.

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

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);
}

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

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

Это сработало как по волшебству.

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

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

Итак, потратив уйму времени, я, наконец, разобрался в этом.Вот как это делается:

  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.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top