Этот вопрос связан с явной неспособностью дизайнера WPF Visual Studio (2008) обрабатывать использование ресурсов, расположенных на уровне App.xaml, если App.xaml находится в отдельной сборке от представления.
Чтобы упростить объяснение проблемы, я создал тестовое приложение. Это приложение имеет две сборки: View и Start. Сборка View содержит окно xaml с именем Window1, а сборка Start включает файл App.xaml. Файл App.xaml в стартовой сборке имеет свой StartupUri, установленный в Window1 в сборке вида. Ни у одного из этих файлов нет кода (за исключением стандартных конструкторов и вызова InitializeComponent ()).
Код для этого примера выглядит следующим образом:
App.xaml:
<Application x:Class="Start.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="pack://application:,,,/View;component/Window1.xaml"
>
<Application.Resources>
<!-- Warning Text Style -->
<Style x:Key="WarningTextStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Application.Resources>
Window1.xaml:
<Window x:Class="View.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Height="300"
Width="300"
>
<Grid>
<TextBlock Text="This is test text" Style="{StaticResource WarningTextStyle}" />
</Grid>
</Window>
Файл Window1.xaml содержит один TextBlock, который ссылается на уровень приложения WarningTextStyle. Этот код прекрасно работает во время выполнения, потому что Window правильно находит ресурс уровня приложения; однако во время разработки дизайнер жалуется, что не может найти WarningTextStyle.
Кто-нибудь знает о чистом и масштабируемом решении этой проблемы?
Мой стандартный подход к крупным приложениям состоит в том, чтобы организовать ресурсы уровня приложения в файлы словарей ресурсов, а затем объединить эти словари в App.xaml. Чтобы обойти проблему, описанную выше, мне нужно объединить эти словари ресурсов с ресурсами каждого представления. Это кажется очень неэффективным, и если позже я добавлю еще один словарь ресурсов, мне нужно будет объединить этот новый словарь с каждым представлением.
Решение «серебряной пули» перенаправит дизайнера на поиск ресурсов уровня приложения. Разумным обходным решением будет объединение словарей ресурсов уровня приложения в каждом представлении, но только во время разработки. Во время выполнения я хотел бы избежать объединения этих словарей в каждом представлении из-за проблем эффективности.
Я попытался объединить словари в каждом представлении в конструкторе выделенного кода представления и затем обернуть эту логику в оператор if, который проверяет метод DesignerProperties.GetIsInDesignMode (); однако конструктор Visual Studio не запускает конструктор представления, поэтому этот подход кажется неудачным.
У кого-нибудь есть лучшее решение или обходной путь?