WPF- 引用资源字典文件时出现编译错误
WPF- Compile error on referencing a Resource Dictionary file
问题:当我在MainWindow.xaml
文件中引用下面的Resource Dictionary
文件时(如下所示),为什么会出现以下编译错误?
CustomWindowStyle resource not found
备注:
- 我正在关注这个 article,其中
Creating A Resource Dictionary File
部分还显示了我正在使用的关于如何在 MainWindow.xaml
中引用资源词典的确切过程
- 如下图所示,当我在
MainWindow.xaml
中键入 Style="{StaticResource ....}
行时,VS2019
确实正确识别了 CustomWindowStyle
。但是在编译的时候(如下图2所示),就抛出了上面的错误。
- 我正在使用
.NET Core 3.1
。我不确定问题是否与 .NET Core 有关
当键入行 Style="{StaticResource ....} 时,智能感知会正确显示选择 CustomWindowStyle 的选项:
编译时,报错:
.
WindowStyle.xaml:
<ResourceDictionary x:Class="WPF_OctDelete.WindowStyle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF_OctDelete">
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="30"
CornerRadius="4"
GlassFrameThickness="0"
NonClientFrameEdges="None"
ResizeBorderThickness="5"
UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="5,30,5,5">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Border>
<DockPanel Height="30"
VerticalAlignment="Top"
LastChildFill="False">
<TextBlock Margin="5,0,0,0"
VerticalAlignment="Center"
DockPanel.Dock="Left"
FontSize="16"
Foreground="White"
Text="{TemplateBinding Title}" />
<Button x:Name="btnClose"
Width="15"
Margin="5"
Click="CloseClick"
Content="X"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
<Button x:Name="btnRestore"
Width="15"
Margin="5"
Click="MaximizeRestoreClick"
Content="#"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
<Button x:Name="btnMinimize"
Width="15"
Margin="5"
VerticalContentAlignment="Bottom"
Click="MinimizeClick"
Content="_"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
</DockPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MainWindow.xaml:
<Window x:Class="WPF_OctDelete.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:local="clr-namespace:WPF_OctDelete"
mc:Ignorable="d"
Style="{StaticResource CustomWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button x:Name="btnTest" Content="Test"/>
</Grid>
</Window>
您的资源是在 window 加载后加载的,因此在 window 加载事件期间无法找到该资源。所以你的方法不会那样工作。
您需要将该资源放入您的 App.xaml 文件中,请参阅 - How to Set the Source of an Image in XAML and in Code Behind to an image in another project in WPF
你的情况(App.xaml)-'
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
然后您可以在 Window -
中使用您的密钥
<Window x:Class="WPF_OctDelete.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:local="clr-namespace:WPF_OctDelete"
mc:Ignorable="d"
Style="{StaticResource CustomWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<!--Rest of your UI Elements-->
</Window>
无需向 window 添加资源,因为它已添加到主应用程序文件中。该资源将在您的整个项目中可用(可用于其他 windows/controls)
(编辑: 进一步说明 - 当您将某些内容作为“StaticResource”添加到您的 window 样式,但稍后加载实际资源时,window “loaded”事件不会拾取它。另一种解决方案是将您的样式称为“DynamicResource”,因此“loaded”事件期间的样式不是静态的,并且会在捕获新资源时更新。)
XAML 处理器从上到下读取 XAML 文件,因此当它尝试解析 CustomWindowStyle
资源时,它还没有加载 ResourceDictionary
.
您可以通过在设置 Style
属性 之前设置 Resources
属性 轻松解决此问题:
<Window x:Class="WPF_OctDelete.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:local="clr-namespace:WPF_OctDelete"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.Style>
<StaticResource ResourceKey="CustomWindowStyle"/>
</Window.Style>
<Grid>
<Button x:Name="btnTest" Content="Test"/>
</Grid>
</Window>
顺序很重要。
问题:当我在MainWindow.xaml
文件中引用下面的Resource Dictionary
文件时(如下所示),为什么会出现以下编译错误?
CustomWindowStyle resource not found
备注:
- 我正在关注这个 article,其中
Creating A Resource Dictionary File
部分还显示了我正在使用的关于如何在MainWindow.xaml
中引用资源词典的确切过程
- 如下图所示,当我在
MainWindow.xaml
中键入Style="{StaticResource ....}
行时,VS2019
确实正确识别了CustomWindowStyle
。但是在编译的时候(如下图2所示),就抛出了上面的错误。 - 我正在使用
.NET Core 3.1
。我不确定问题是否与 .NET Core 有关
当键入行 Style="{StaticResource ....} 时,智能感知会正确显示选择 CustomWindowStyle 的选项:
编译时,报错:
WindowStyle.xaml:
<ResourceDictionary x:Class="WPF_OctDelete.WindowStyle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF_OctDelete">
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="30"
CornerRadius="4"
GlassFrameThickness="0"
NonClientFrameEdges="None"
ResizeBorderThickness="5"
UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="5,30,5,5">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Border>
<DockPanel Height="30"
VerticalAlignment="Top"
LastChildFill="False">
<TextBlock Margin="5,0,0,0"
VerticalAlignment="Center"
DockPanel.Dock="Left"
FontSize="16"
Foreground="White"
Text="{TemplateBinding Title}" />
<Button x:Name="btnClose"
Width="15"
Margin="5"
Click="CloseClick"
Content="X"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
<Button x:Name="btnRestore"
Width="15"
Margin="5"
Click="MaximizeRestoreClick"
Content="#"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
<Button x:Name="btnMinimize"
Width="15"
Margin="5"
VerticalContentAlignment="Bottom"
Click="MinimizeClick"
Content="_"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
</DockPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MainWindow.xaml:
<Window x:Class="WPF_OctDelete.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:local="clr-namespace:WPF_OctDelete"
mc:Ignorable="d"
Style="{StaticResource CustomWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button x:Name="btnTest" Content="Test"/>
</Grid>
</Window>
您的资源是在 window 加载后加载的,因此在 window 加载事件期间无法找到该资源。所以你的方法不会那样工作。
您需要将该资源放入您的 App.xaml 文件中,请参阅 - How to Set the Source of an Image in XAML and in Code Behind to an image in another project in WPF
你的情况(App.xaml)-'
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
然后您可以在 Window -
中使用您的密钥<Window x:Class="WPF_OctDelete.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:local="clr-namespace:WPF_OctDelete"
mc:Ignorable="d"
Style="{StaticResource CustomWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<!--Rest of your UI Elements-->
</Window>
无需向 window 添加资源,因为它已添加到主应用程序文件中。该资源将在您的整个项目中可用(可用于其他 windows/controls)
(编辑: 进一步说明 - 当您将某些内容作为“StaticResource”添加到您的 window 样式,但稍后加载实际资源时,window “loaded”事件不会拾取它。另一种解决方案是将您的样式称为“DynamicResource”,因此“loaded”事件期间的样式不是静态的,并且会在捕获新资源时更新。)
XAML 处理器从上到下读取 XAML 文件,因此当它尝试解析 CustomWindowStyle
资源时,它还没有加载 ResourceDictionary
.
您可以通过在设置 Style
属性 之前设置 Resources
属性 轻松解决此问题:
<Window x:Class="WPF_OctDelete.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:local="clr-namespace:WPF_OctDelete"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.Style>
<StaticResource ResourceKey="CustomWindowStyle"/>
</Window.Style>
<Grid>
<Button x:Name="btnTest" Content="Test"/>
</Grid>
</Window>
顺序很重要。