5

简短的

我创建了一个漂亮的WindowChrome样式来应用到我的窗户上。但是,当我添加ContentControl到我的样式时,应用程序会进入中断模式。

我已经将这个 youtube 视频这篇文章这个 SO 问题Microsoft 文档中的代码拼凑在一起,并且我想出了以下代码。

注意:下面的代码都被认为是相关的,因为应用程序无法使用这些部分中的任何一个运行(是的,我知道它可以在没有代码隐藏的情况下运行,但是不得不从 Visual Studio 而不是关闭按钮停止应用程序很烦人 - 其中也是我想要完成的)。我实际上已经精简了下面的代码,以便更容易使用。


代码

窗口.xaml

<Style x:Key="TestWindow" TargetType="{x:Type Window}">
    <Setter Property="Background" Value="#FF222222"/>
    <Setter Property="BorderBrush" Value="WhiteSmoke"/>
    <Setter Property="BorderThickness" Value="5,30,5,5"/>
    <Setter Property="WindowChrome.WindowChrome">
        <Setter.Value>
            <WindowChrome CaptionHeight="20"
                          CornerRadius="0"
                          GlassFrameThickness="0,0,0,-1"
                          NonClientFrameEdges="None"
                          ResizeBorderThickness="5"
                          UseAeroCaptionButtons="True"/>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">

                <Grid>

                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <AdornerDecorator>
                            <ContentPresenter/>
                        </AdornerDecorator>
                    </Border>

                    <DockPanel LastChildFill="True" VerticalAlignment="Top" Height="30">

                        <StackPanel DockPanel.Dock="Right"
                                    Orientation="Horizontal"
                                    VerticalAlignment="Center">
                            <Button x:Name="Button_Close"
                                    WindowChrome.IsHitTestVisibleInChrome="True"
                                    Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
                                    Click="CloseClick">
                                <ContentControl Template="{StaticResource Icon_Close}" Height="10"/>
                            </Button>
                        </StackPanel>

                        <StackPanel DockPanel.Dock="Left"
                                    Orientation="Horizontal"
                                    VerticalAlignment="Center">
                            <Image x:Name="PART_WindowCaptionIcon"
                                   Width="16"
                                   Height="16"
                                   Margin="0,0,6,0"
                                   Source="{TemplateBinding Icon}"/>
                            <TextBlock x:Name="PART_WindowCaptionText"
                                       Margin="6,0,0,0"
                                       Padding="0">
                                <Run BaselineAlignment="Center"
                                     Text="{TemplateBinding Title}"
                                     Foreground="Black"/>
                            </TextBlock>
                        </StackPanel>

                    </DockPanel>

                </Grid>

                <ControlTemplate.Triggers>
                    <Trigger SourceName="PART_WindowCaptionIcon" Property="Source" Value="{x:Null}">
                        <Setter TargetName="PART_WindowCaptionIcon" Property="Visibility" Value="Collapsed"/>
                        <Setter TargetName="PART_WindowCaptionText" Property="Margin" Value="5,0,0,0"/>
                    </Trigger>
                </ControlTemplate.Triggers>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

图标.xaml

Window.xaml通过引用此文件的ContentControl Template属性值App.xaml

<ControlTemplate x:Key="Icon_Close">
    <Viewbox>
        <Polygon Points="357,35.7 321.3,0 178.5,142.8 35.7,0 0,35.7 142.8,178.5 0,321.3 35.7,357 178.5,214.2 321.3,357 357,321.3 214.2,178.5" Fill="Black"/>
    </Viewbox>
</ControlTemplate>

窗口.xaml.cs

public partial class Window : ResourceDictionary
{
    public Window()
    {
        InitializeComponent();
    }

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

问题

当该行<ContentControl Template="{StaticResource Icon_Close}" Height="10"/>存在时(第 38 行),将收到以下消息。当同一行被删除/注释掉时,应用程序在不进入中断模式的情况下运行。

消息:应用程序处于中断模式

查看输出窗口,我收到以下消息:

An unhandled exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.

问题

此代码在直接放在 的 XAML 代码中时有效Window,但是当我尝试将其放在模板中时它失败了。

我的问题是:

  1. 为什么我的应用程序放在的模板中时会进入中断模式?ContentControlWindow
  2. 我该如何解决这个问题?
    • 请注意,我必须使用文件中的 my ControlTemplateIcons.xaml并且对此内容的调用必须保留在窗口中Style(而不是窗口的实际 xaml)。
4

1 回答 1

1

简短的

根据这个问题的答案,问题是由于我的样式顺序不正确。我将我的问题标记为该问题的副本,但我觉得我应该分享这个作为答案,以防它帮助其他人。

我喜欢微软没有适当的例外处理这个问题,你需要用头撞墙,直到你的头或墙破裂。

代码

我的App.xaml包含以下代码ResourceDictionary.MergedDictionaries

<ResourceDictionary Source="pack://application:,,,/MyProject;component/Window.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MyProject;component/Icons.xaml"/>

我将顺序更改为以下

<ResourceDictionary Source="pack://application:,,,/MyProject;component/Icons.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MyProject;component/Window.xaml"/>
于 2017-12-15T16:49:10.193 回答