我遇到的情况是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中应用的 StaticResource 来解析按钮的样式(背景和边框画笔)的.xaml 即可。如果我使用 DynamicResource ,则会正确找到画笔并将其应用于Button。任何有关此行为发生的见解。
修改:
根据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
正确定位资源答案 0 :(得分: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。
我希望有所帮助。