WPF- 引用资源字典文件时出现编译错误

WPF- Compile error on referencing a Resource Dictionary file

问题:当我在MainWindow.xaml文件中引用下面的Resource Dictionary文件时(如下所示),为什么会出现以下编译错误?

CustomWindowStyle resource not found

备注:

  1. 我正在关注这个 article,其中 Creating A Resource Dictionary File 部分还显示了我正在使用的关于如何在 MainWindow.xaml
  2. 中引用资源词典的确切过程
  3. 如下图所示,当我在 MainWindow.xaml 中键入 Style="{StaticResource ....} 行时,VS2019 确实正确识别了 CustomWindowStyle。但是在编译的时候(如下图2所示),就抛出了上面的错误。
  4. 我正在使用 .NET Core 3.1。我不确定问题是否与 .NET Core
  5. 有关

当键入行 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>

顺序很重要。