自定义窗口类和装饰层

J.迈耶

出于设计目的,我实现了一个带有样式的自定义窗口类。所述StylableWindow从窗口继承和主要实现一些依赖属性(例如,用于一个标题栏背景颜色),做了一些边界上的图标,标题栏和附加menubay调整逻辑和把手鼠标交互。

当我尝试获取 AdornerLayer(使用 AdornerLayer.GetAdornerLayer(uiElement) 方法)时,结果总是为null

经过一番调查,我尝试用常规窗口替换我的自定义窗口,瞧我的装饰器按预期工作。

不,我的问题是:我在自定义窗口实现中做错了什么,以至于 WPF 找不到任何 AdornerLayer?

这是我对样式的实现。由于 StylableWindow.cs 主要由依赖属性和交互逻辑组成,因此我认为代码对此目的不是很有帮助。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:stylableWindow="clr-namespace:StylableWindow">

    <!--Base style for title bar buttons-->
    <Style x:Key="CaptionButtonStyle" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid x:Name="LayoutRoot" Background="Transparent" Width="44" Height="30">
                        <TextBlock x:Name="txt" Text="{TemplateBinding Content}" FontFamily="Segoe MDL2 Assets" FontSize="10" 
                                   Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"
                                   RenderOptions.ClearTypeHint="Auto" TextOptions.TextRenderingMode="Aliased"  TextOptions.TextFormattingMode="Display"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="LayoutRoot" Property="Background" Value="#E5E5E5"/>
                            <Setter TargetName="txt" Property="Foreground" Value="#000000"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!--Minimize-->
    <Style x:Key="MinimizeButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyle}">
        <Setter Property="Content" Value="&#xE949;"/>
    </Style>

    <!--Maximize-->
    <Style x:Key="MaximizeButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyle}">
        <Setter Property="Content" Value="&#xE739;"/>
    </Style>

    <!--Restore-->
    <Style x:Key="RestoreButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyle}">
        <Setter Property="Content" Value="&#xE923;"/>
    </Style>

    <!--Close-->
    <Style x:Key="CloseButtonStyle" TargetType="Button" BasedOn="{StaticResource CaptionButtonStyle}">
        <Setter Property="Content" Value="&#xE106;"/>
    </Style>

    <Style TargetType="stylableWindow:StylableWindow" x:Key="StylableWindowStyle">
        <Setter Property="Background" Value="{Binding Background}"/>
        <Setter Property="BorderBrush" Value="Black"/>
        <Setter Property="MinHeight" Value="10"/>
        <Setter Property="MinWidth" Value="200"/>
        <Setter Property="RenderOptions.BitmapScalingMode" Value="HighQuality"/>
        <Setter Property="Title" Value="{Binding Title}"/>
        <Setter Property="Icon" Value="{Binding Icon}"/>
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome GlassFrameThickness="1" 
                              ResizeBorderThickness="4"
                              CaptionHeight="0"/>
            </Setter.Value>
        </Setter>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type stylableWindow:StylableWindow}">

                    <Grid Background="Transparent" x:Name="WindowRoot">

                        <Grid x:Name="LayoutRoot"
                              Background="{TemplateBinding Background}">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="30"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>

                            <!--TitleBar-->
                            <Grid x:Name="PART_HeaderBar"
                                  Background="{TemplateBinding HeaderBarBackground}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>

                                <ContentControl Grid.Column="0"
                                                x:Name="AppIcon"
                                                ContentTemplate="{TemplateBinding HeaderBarIcon}"
                                                Margin="6 0 10 0">
                                </ContentControl>

                                <ContentControl Grid.Column="1" 
                                                Content="{TemplateBinding HeaderBarMenu}">
                                </ContentControl>

                                <Rectangle Grid.Column="2" Width="Auto" Height="20" Stroke="{TemplateBinding HeaderBarForeground}" Visibility="{TemplateBinding TitleBorderVisibility}" Margin="0 2 0 0"/>
                                <TextBlock Text="{TemplateBinding Title}" 
                                           Grid.Column="2"
                                           TextTrimming="CharacterEllipsis"
                                           FontSize="14"
                                           TextAlignment="Center"
                                           VerticalAlignment="Center"
                                           Padding="10 0 10 0"
                                           Foreground="{TemplateBinding HeaderBarForeground}"
                                           Panel.ZIndex="0"
                                           IsEnabled="{TemplateBinding IsActive}"/>

                                <Grid x:Name="WindowControlsGrid" Grid.Column="4" Background="Transparent">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition/>
                                        <ColumnDefinition/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>

                                    <Button x:Name="MinimizeButton"
                                            Foreground="{TemplateBinding HeaderBarForeground}"
                                            Style="{StaticResource MinimizeButtonStyle}" 
                                            Visibility="{TemplateBinding MinMaxVisibility}"
                                            Grid.Column="0"/>
                                    <Button x:Name="MaximizeButton" 
                                            Foreground="{TemplateBinding HeaderBarForeground}"
                                            Style="{StaticResource MaximizeButtonStyle}" 
                                            Visibility="{TemplateBinding MinMaxVisibility}"
                                            Grid.Column="1"/>
                                    <Button x:Name="RestoreButton" 
                                            Foreground="{TemplateBinding HeaderBarForeground}"
                                            Style="{StaticResource RestoreButtonStyle}" 
                                            Visibility="Collapsed"
                                            Grid.Column="1"/>
                                    <Button x:Name="CloseButton" 
                                            Foreground="{TemplateBinding HeaderBarForeground}"
                                            Style="{StaticResource CloseButtonStyle}" 
                                            Grid.Column="2"/>
                                </Grid>
                            </Grid>

                            <Grid x:Name="PART_MainContentGrid"
                                  Grid.Row="1"
                                  Panel.ZIndex="10">
                                <ContentPresenter x:Name="PART_MainContentPresenter" Grid.Row="0"/>
                            </Grid>
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!--<Style TargetType="{x:Type Window}" BasedOn="{StaticResource StylableWindowStyle}"/>-->

</ResourceDictionary>
<StylableWindow Style="{StaticResource StylableWindowStyle}">
    <StylableWindow.HeaderBarMenu>
        <!-- a menu bar for the title -->
    </StylableWindow.HeaderBarMenu>

    <Grid>
   <!-- content goes here -->
    </Grid>
</StylableWindow>
凯瑟网

在你的控制模板中ContentPresenter,用AdornerDecorator这样的方式包裹你

...
<Grid x:Name="PART_MainContentGrid"
    Grid.Row="1"
    Panel.ZIndex="10">
    <AdornerDecorator>
        <ContentPresenter x:Name="PART_MainContentPresenter" Grid.Row="0"/>
    </AdornerDecorator>
</Grid>
...

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章