首页 文章

组织Xaml - 无法从不同的xaml文件应用StaticResource

提问于
浏览
0

我有一种情况,wpf应用程序无法拾取StaticResource,而是使用 XamlParseException 失败 . 但是,如果我使用DynamicResource,则会找到资源并且不会发生异常 .

我试图按照http://projekt202.com/blog/2010/xaml-organization/的建议设计和组织wpf资源

我有相应的2个项目,一个包含所有资源的wpf控件库和一个使用这些资源的主要wpf项目 . 这是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>

如前文所述,我无法使用 ButtonStyle.xaml 中应用的 StaticResource 来解析 Button 的样式(背景和边框画笔) . 如果我使用 DynamicResource ,则可以正确找到画笔并将其应用于Button . 任何有关此行为发生的见解 .

Edit:
根据Mike的建议,我将 Wpf_Theme.ControlLibrary 项目中的xaml文件直接包含到Main项目的 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正确定位和资源

1 回答

  • 0

    静态资源引用在分析时解析(大部分),而动态引用在运行时解析 . 这意味着只有在引用之前已经解析了资源时才能使用静态引用,而动态引用可以用作稍后定义的资源的前向引用 .

    资料来源:http://drwpf.com/blog/category/resources/

    当两个ResourceDictionaries在一个separte程序集中并且你同时引用它们时我会猜测这个处理是在同一时间发生的 . 而如果您直接在App.xaml中加载它们,则可以确保它们按正确的顺序加载 .

    因此,您的第一个词典的资源不可用于第二个词典,因为您将它们包含在同一个词典中 .

    有两种方法可以解决问题 . 您可以使用在运行时评估的DynamicResources(就像您已经尝试过的那样) .

    另一种解决方案,如果您现在是资源字典的hyrachie,您可以做几个级别 . 喜欢:

    <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 .

    我希望有所帮助 .

相关问题