wpf System.Windows.Markup.XamlParseException:“”在将样式应用于窗口时,为“System.Windows.StaticResourceExtension”提供值引发了异常

ifsvaxew  于 2023-02-05  发布在  Windows
关注(0)|答案(1)|浏览(407)

我尝试将样式应用到我的应用程序中的特定WPF窗口,而不是所有窗口。基本上,我想改变样式只是因为我想让窗口标题栏看起来不同。我已经看到,从net Framework 4.5开始,有一个WindowChrome类,它允许自定义窗口框架和标题栏,而不触及功能(标准窗口行为:调整大小、移动等)。
所以我发现这个有趣的article,它解释了如何做。
它包括创建字典资源文件(.xaml):

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

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

并附加到其代码隐藏(xaml.cs),因此Visual Studio将其视为资源文件的代码隐藏文件。

using System.Windows;

namespace myApp.Styles
{
    public partial class WindowStyle : ResourceDictionary
    {
        public WindowStyle()
        {
            InitializeComponent();
        }

        private void CloseClick(object sender, RoutedEventArgs e)
        {
            var window = (Window)((FrameworkElement)sender).TemplatedParent;
            window.Close();
        }

        private void MaximizeRestoreClick(object sender, RoutedEventArgs e)
        {
            var window = (Window)((FrameworkElement)sender).TemplatedParent;
            if (window.WindowState == WindowState.Normal)
            {
                window.WindowState = WindowState.Maximized;
            }
            else
            {
                window.WindowState = WindowState.Normal;
            }
        }

        private void MinimizeClick(object sender, RoutedEventArgs e)
        {
            var window = (Window)((FrameworkElement)sender).TemplatedParent;
            window.WindowState = WindowState.Minimized;
        }
    }
}

现在我尝试将该样式应用到我的特定WPF窗口(不是所有窗口),如下所示。
我的对话框视图.xaml:

<Window x:Class="myApp.Views.myDialogView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:v="clr-namespace:myApp.Views"
        xmlns:vm="clr-namespace:myApp.ViewModels"
        mc:Ignorable="d" 
        d:DesignHeight="450" d:DesignWidth="800"
        ResizeMode="NoResize"
        SizeToContent="WidthAndHeight"
        Style="{StaticResource CustomWindowStyle}" 
        WindowStyle="None">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/pEp;component/Resources/Styles/WindowStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <DataTemplate DataType="{x:Type vm:myViewModel1}">
                <v:myView1 />
            </DataTemplate>
            <DataTemplate DataType="{x:Type vm:myViewModel2}">
                <v:myView2 />
            </DataTemplate>
        </ResourceDictionary>
    </Window.Resources>
</Window>

样式在设计时正确应用于我的窗口,但当我尝试打开该窗口时调用InitializeComponent()时,在运行时构造函数中抛出以下异常:
myDialogView.xaml.cs:

namespace myApp.Views
{
    public partial class myDialogView : Window
    {
        public myDialogView()
        {
            InitializeComponent();
        }
    }
}

内部异常:异常:找不到名为“CustomWindowStyle”的资源。资源名称区分大小写。
要打开我的WPF窗口,我只需执行以下操作:

var myWindow = new myApp.Views.myDialogView();
myWindow.DataContext = new myApp.ViewModels.myDialogViewModel();
myWindow.ShowDialog();
mlmc2os5

mlmc2os51#

窗口标签内的资源在被引用后被加载,Xaml从上到下,从标签外到标签内都变成了控件。
您可以合并app.xaml中的资源字典。
或者
尝试将其用作动态资源而不是静态资源。

相关问题