2015-03-13 2 views
0

У меня возникла ситуация, когда приложение wpf не может получить StaticResource и вместо этого выходит из строя с XamlParseException. Но если вместо этого я использовал DynamicResource, ресурс будет найден, и исключение не произойдет.Организация Xaml - Невозможно применить StaticResource из другого файла xaml

Я пытался организовать стиль и МОФ ресурсы, как это рекомендовано в http://projekt202.com/blog/2010/xaml-organization/

У меня есть 2 проектов соответственно, библиотека управления МОФ, что дома все ресурсы и основной МОФ проект, который использует эти ресурсы. Вот структура 2 проектов

Projects Structure 

Wpf_Theme.ControlLibrary
--ResourceDictionaries
---- BaseControlStyles
------ ButtonStyle.xaml
----- -TextBoxStyle.xaml
---- Кисти
------ DefaultBlueTheme
---- ResourceLibrary.xaml
Wpf_Theme.Main
--App.xaml
--MainWindow.xaml


Contents of xaml files 

ButtonStyle.xaml

<Style TargetType="{x:Type Button}"> 
    <Setter Property="Background" Value="{StaticResource ControlBackground}"/> 
    <Setter Property="BorderBrush" Value="{StaticResource BorderColor}"/> 
    ... 
</Style> 

DefaultBlueTheme.xaml (Кисть)

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <SolidColorBrush x:Key="PanelBackground" Color="#C8DCF0"/> 
    <SolidColorBrush x:Key="BorderColor" Color="#6A8FB5"/> 
    <SolidColorBrush x:Key="SelectedItemBackground" Color="Wheat"/> 
    <SolidColorBrush x:Key="TextForeground" Color="Black"/> 

    <LinearGradientBrush x:Key="ControlBackground" StartPoint="0,0" EndPoint="0,1"> 
     <LinearGradientBrush.GradientStops> 
      <GradientStop Offset="0" Color="#DBECFD"/> 
      <GradientStop Offset="0.5" Color="#C7DBEF"/> 
      <GradientStop Offset="1" Color="#B0CAE5"/> 
     </LinearGradientBrush.GradientStops> 
    </LinearGradientBrush> 
</ResourceDictionary> 

ResourceLibrary.xaml (Слияния всех словарей в одном файл, который будет использоваться основным проектом)

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="Brushes/DefaultBlueTheme.xaml"/> 
     <ResourceDictionary Source="BaseControlStyles/ButtonStyle.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
</ResourceDictionary> 

App.xaml (В главном проекте)

<Application x:Class="Wpf_Themes.Main.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      StartupUri="MainWindow.xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary 
        Source="/Wpf_Themes.ControlLibrary;component/ResourceDictionaries/ResourceLibrary.xaml"/> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

MainWindow.xaml

<Window x:Class="Wpf_Themes.Main.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 

    <StackPanel Width="200" Margin="10"> 
     <Button>Click Me</Button> 
    </StackPanel> 
</Window> 

Как уже говорилось ранее в этой должности, я не в состоянии решить стиль (фона и границы кисти) для Button с помощью StaticResource применяется в ButtonStyle.xaml. Если вместо этого я использую DynamicResource, кисти найдены правильно и применяются к кнопке. Любые идеи, почему это происходит.


Edit:
По предложению Майка, я включил в XAML файлы из проекта Wpf_Theme.ControlLibrary непосредственно в App.xaml главного проекта, как ниже

App. xaml

<Application x:Class="Wpf_Themes.Main.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      StartupUri="MainWindow.xaml"> 
    <Application.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="/Wpf_Themes.ControlLibrary;component/ResourceDictionaries/Brushes/DefaultBlueTheme.xaml"/> 
       <ResourceDictionary Source="/Wpf_Themes.ControlLibrary;component/ResourceDictionaries/BaseControlStyles/ButtonStyle.xaml"/> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Application.Resources> 
</Application> 

и ресурсы сейчас правильно размещен с использованием StaticResource

+0

Есть ли какая-то особая причина, почему вам необходимо использовать ваш ** ResourceLibrary.xaml ** файл? Не могли бы вы просто объединить все словари в ** App.xaml **? –

+0

На самом деле я следил за сайтом, упомянутым ранее. Я думаю, что его там, чтобы избежать синтаксиса uri сборки для включения xaml. Вместо этого один файл встроен с помощью esourceLibrary.xaml. Интересно, если я избегу ResourceLibrary.xaml и вместо этого внедряю все словари непосредственно в App.xaml, он работает, и ресурсы правильно расположены. Не уверен, хотя почему! – Jatin

ответ

0

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

Источник: http://drwpf.com/blog/category/resources/

Когда два ResourceDictionaries находятся в separte Ассамблеи и вы ссылаться на них в то же время я думаю, что эта обработка происходит в то же самое время. Если вы загрузите их непосредственно в App.xaml, то они будут загружены в правильном порядке.

Итак, ресурсы вашего первого Словаря недоступны для второго Словаря, поскольку вы включаете их в один Словарь.

Существует два способа решения проблемы. Либо вы используете DynamicResources, которые evalutated во время выполнения (как вы уже пробовали).

Другое решение, если вы теперь можете использовать ваши словари ресурсов, вы можете сделать несколько уровней. Как:

<Application x:Class="WPF_Theme.App" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     StartupUri="MainWindow.xaml"> 
<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="pack://application:,,,/ControlLibrary;component/ResourceDictionaries/BaseLevel.xaml" /> 
      <ResourceDictionary Source="pack://application:,,,/ControlLibrary;component/ResourceDictionaries/SecondLevel.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

BaseLevel.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="Brushes/DefaultBlueTheme.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 
</ResourceDictionary> 

SecondLevel.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="BaseControlStyles/ButtonStyle.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 
</ResourceDictionary> 

DefaultBlueTheme.xaml и ButtonStyle.xaml остается неизменным.

С этим вы должны убедиться, что различные ResourceDictionaries уже есть, если они вам понадобятся.

Я надеюсь, что это поможет.

+0

Как указано в комментарии к ответу Майка, я сейчас слияние словарей (ButtonStyle.xaml, DefaultBlueTheme.xaml, ...) в App.xaml прямо из основного проекта, и он работает хорошо. См. Править на мой вопрос – Jatin

Смежные вопросы