Подтвердить что ты не робот

Сквозные стили в корневом уровне в библиотеке классов WPF

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

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

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

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

4b9b3361

Ответ 1

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

Style={DynamicResource MyStyle}

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

р. WPF (или человек, ранее известный как доктор 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 };

Он работал как шарм.

Ответ 5

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

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

Ответ 6

Поэтому, потратив много времени, я наконец понял это. Вот как:

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

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

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

Примечания:

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

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