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

Как ссылаться на клавиши стиля WPF, определенные в отдельной сборке в другой библиотеке

У меня есть две библиотеки и один макет проекта сборки приложений, и мне интересно, как я могу ссылаться на стили по их ключу в одной из моих библиотек, которые определены в другой.

Схема моего решения:

  • WpfControls.dll - содержит общие элементы многократного использования, такие как элемент управления NumericUpDown на основе WPF, а также другие базовые элементы управления и некоторые стили, которые я хотел бы сделать повторно используемыми. Ради примера можно сказать, что мой ключ стиля здесь определяется как MyButtonStyle.
  • SpecializedControls.dll. Удерживает элементы управления, которые специализированы для нашего приложения, такие как настраиваемые составные элементы управления и UserControls в WPF. Здесь я хотел бы ссылаться на стиль MyButtonStyle, определенный в сборке WpfControls.dll.
  • Application.exe. Эта сборка использует элементы управления, определенные в сборке SpecializedControls.dll.

Я видел несколько примеров, объясняющих, как это сделать с помощью простой единой библиотеки управления и сборки приложения, но в моем случае у меня есть две сборки и приложение. Таким образом, другими словами, в моем случае у меня нет App.xaml в моей второй библиотеке управления, где я мог бы использовать концепцию MergeDictionaries. Я уверен, что если бы мне захотелось добавить ссылку MergedDictionaries непосредственно в каждый элемент управления XAML, чтобы объединить все Generic.xaml, определенные в сборке WpfControls.dll, но я предполагаю, что это приведет к тому, что стили будут излишне слиты в разные места в моей сборке SpecializedControls, которая не кажется лучшим решением. Что еще хуже, эти словари также могут быть объединены в Application.exe, это начинает раздувать мое приложение во время выполнения?

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

Обновление. После немного более сложного тестирования кажется, что у меня возникли проблемы с ссылкой на любой ресурс, определенный в Generic.xaml, его ключом даже внутри той же сборки. Возможно, что-то совершенно не так, как я понимаю, как работают ключи ресурсов, поэтому мне придется немного больше исследований, а также изучить ComponentResourceKey. Если у кого-нибудь есть какие-либо намеки или предложения, пожалуйста, помогите.

4b9b3361

Ответ 1

Поиск ресурсов в WPF работает в иерархии: вверх по логическому дереву, затем ресурсам приложений, тематическим ресурсам и, наконец, системным ресурсам.

Ресурсы темы обычно могут быть доступны только неявно (даже в пределах сборки, которую они определены). Это относится только к стилям, где TargetType может использоваться как неявный ключ.

Чтобы выполнить то, что вы пытаетесь сделать, есть два варианта:

  • Используйте ComponentResourceKey. Это специальный ключ ресурса, который позволяет ссылаться на ресурсы из других сборок. Например, вы можете определить кисть в словаре темы WpfControls:

    <LinearGradientBrush x:Key="{ComponentResourceKey TypeInTargetAssembly=local:MyClass, ResourceId=MyBrush}">
        <GradientStop Color="Red" />
        <GradientStop Color="Blue" Offset="1" />
    </LinearGradientBrush>
    

    И затем вы можете ссылаться на него в SpecializedControls:

    <UserControl Background="{StaticResource {ComponentResourceKey TypeInTargetAssembly=wpfControls:MyClass, ResourceId=MyBrush}}" />
    
  • Используйте MergedDictionaries, чтобы импортировать словарь в ресурсы приложения. Вы можете сделать это в сборке приложений, и когда приложение загрузится, даже те элементы управления, которые находятся в SpecializedControls, смогут использовать эти ресурсы. У вас возникнет проблема с опытом разработки в этом сценарии, который вы можете решить, поставив поддельный App.xaml в SpecializedControls, который также будет содержать ссылку на словарь.

Надеюсь, что это поможет,

Aelij.

Ответ 2

Принятый ответ правильный, я просто объясняю, как использовать MergedDictionaries

В App.xaml,

    <Application.Resources>
      <ResourceDictionary>
         <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/-YourDllName-;component/-DirectoryName-/FileName.xaml"/>
            <!-- Use Below syntax if your resource file is not inside a directory(in root) -->
            <ResourceDictionary Source="pack://application:,,,/-YourDllName-;component/FileName.xaml"/>
         </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
    </Application.Resources>