StaticResource не найден при использовании элемента управления WPF в другой сборке

Я создал WPF UserControl и хочу сослаться на него в другом проекте. Но даже несмотря на то, что UserControl можно использовать в своей собственной сборке, при ссылке в другом проекте возникает проблема StaticResource not found.

Мой UserControl выглядит так:

<UserControl x:Class="DiagramDesigner.VacSymGrmV"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:DiagramDesigner"
             xmlns:s="clr-namespace:DiagramDesigner"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <local:DesignerCanvas Focusable="true"  x:Name="vacgrm"                         
                            Background="{StaticResource WindowBackgroundBrush}"
                            Margin="10" FocusVisualStyle="{x:Null}"
                            ContextMenu="{StaticResource DesignerItemContextMenu}"/>
    </Grid>
</UserControl>

Проблемный момент: {Static Resource WindowBackgroundBrush}, который является ресурсом, определенным в файле XAML:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
   <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
   <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#000" />
   <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
</ResourceDictionary>

Эта сборка является EXE, и в окне дизайна UserControl я вижу, что она правильно отображается, компилируется и запускается.

Но когда я хочу использовать UserControl в другом приложении WPF, как в следующем коде, это приложение выдает исключение при запуске, утверждая, что WindowBackgroundBrush не найдено:

<Window x:Class="XVacSysComp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:vac="clr-namespace:DiagramDesigner;assembly=VacSymDgm"
        xmlns:local="clr-namespace:XVacSysComp;assembly=XVacSysComp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <vac:VacSymGrmV>
  
        </vac:VacSymGrmV>
    </Grid>
</Window>

VacSymGrmV это UserControl и неудивительно, что UserControl неправильно отображается в окне дизайна.

Исключение говорит:

Исключение: «WindowBackgroundBrush» не найден, и обратите внимание на верхний/нижний регистр...

Это какая-то проблема, связанная с расположением статического ресурса при его использовании в другой сборке?


person Chengting    schedule 07.01.2021    source источник
comment
Является ли этот ResourceDictionary импортированным где-либо, например. добавлено в MergedDictionaries ресурсов UserControl?   -  person Clemens    schedule 07.01.2021
comment
UserControl не имеет собственного ресурса. На самом деле раздел ‹local:DesignerCanvas.. изначально используется в главном окне приложения WPF. Я только что извлек этот раздел и обернул его в UserControl. Потому что я хочу использовать его в качестве элемента управления в других приложениях.   -  person Chengting    schedule 07.01.2021
comment
О, действительно, ресурсный xaml, содержащий WindowBackgroundBrush, появляется в некоторых других файлах ресурсов.   -  person Chengting    schedule 07.01.2021


Ответы (2)


Исключение сообщает вам точную проблему, WindowBackgroundBrush не найден.

'WindowBackgroundBrush' не найден, обратите внимание на верхний/нижний регистр...

Ресурс определен в словаре ресурсов, который вы объединили в любом месте содержащей сборки (EXE), например. ресурсы приложения. Если вы используете там пользовательский элемент управления, статический ресурс может быть разрешен.

Однако если вы используете пользовательский элемент управления из другого приложения, как это приложение будет автоматически получать доступ к ресурсам из любой другой сборки? Даже если ваш пользовательский элемент управления будет расположен в сборке (EXE) вашего исходного приложения, просто ссылка на него из другого приложения или библиотеки не загрузит другое приложение WPF или волшебным образом не добавит указанные ресурсы оттуда в исполняемую сборку.

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

<ResourceDictionary>
   <!-- ...other resources. -->
   <ResourceDictionary.MergedDictionaries>
      <!-- ...other resource dictionaries. -->
      <ResourceDictionary Source="pack://application:,,,/MySharedAssembly;component/MySharedResourceDictionary.xaml" />
   </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Дополнительные сведения о ссылке на словарь ресурсов из сборки, на которую указывает ссылка, и исходный синтаксис, использованный в примере, см. на упаковать документацию по URI.

В зависимости от вашего сценария вы также можете объединить и предоставить ресурсы с вашим пользовательским элементом управления, но я предполагаю, что для рассматриваемого ресурса это не применимо, так как это фон приложения.

person thatguy    schedule 07.01.2021
comment
Я действительно считал само собой разумеющимся, что нахождение в одной и той же сборке даст пользователю привилегию управления прямым доступом к ресурсу, что не так. Спасибо большое. - person Chengting; 07.01.2021
comment
@Chengting stackoverflow вместо этого рекомендует отметить приемлемый ответ, спасибо, это поможет другим найти хорошие ответы - person Lana; 07.01.2021

Вы должны импортировать свой словарь ресурсов в свой UserControl

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="YourDictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>
person Lana    schedule 07.01.2021