zl程序教程

您现在的位置是:首页 >  .Net

当前栏目

WPF自定义标题栏

2023-03-31 10:59:30 时间

往往原有的标题栏无法满足需求,此时就需要进行自定义标题栏。


重新定义Window的Template

首先,需修改WindowChrome的几个属性

CaptionHeight属性值就是自定义标题栏的高,若值低于自定义窗体模板中的标题部分的高,可能会导致,鼠标点击标题栏无法拖动,因为鼠标此时可能不在CaptionHeight范围之内,所以导致无法拖动。

要使没有玻璃框架的自定义窗口,请将 GlassFrameThickness 属性设置为统一值 0

    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="100" UseAeroCaptionButtons="False" GlassFrameThickness="1" />
    </WindowChrome.WindowChrome>

自定义窗体模板,此时需要用到占位符ContentPresenter来替窗体工作区的内容进行占位,在非工作区中启用交互式元素需 WindowChrome.IsHitTestVisibleInChrome="True"

<Window.Template>
        <ControlTemplate TargetType="{x:Type Window}">
            <AdornerDecorator>
                <Grid x:Name="grid">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="100" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <Grid Grid.Row="0">
                        <StackPanel
                            HorizontalAlignment="Right"
                            Orientation="Horizontal"
                            WindowChrome.IsHitTestVisibleInChrome="True">
                            <Button
                                Command="{Binding MinWindowCmd}"
                                CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                                Content="最小化" />
                            <Button
                                Command="{Binding MaxWindowCmd}"
                                CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                                Content="最大化" />
                            <Button
                                Command="{Binding CloseWindowCmd}"
                                CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                                Content="关闭" />
                        </StackPanel>
                    </Grid>
                    <ContentPresenter Grid.Row="1" />
                </Grid>
            </AdornerDecorator>
            <ControlTemplate.Triggers>
                <Trigger Property="WindowState" Value="Maximized">
                    <Setter TargetName="grid" Property="Margin" Value="8" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Window.Template>
View Code

ViewModel代码:

        #region 窗口最小化

        /// <summary>
        /// 窗口最小化
        /// </summary>
        private void MinWindow(Window window)
        {
            window.WindowState = WindowState.Minimized;
        }

        #endregion

        #region 窗口最大化与还原

        /// <summary>
        /// 窗口最大化与还原
        /// </summary>
        private void MaxWindow(Window window)
        {
            window.WindowState = window.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
        }

        #endregion

        #region 窗口关闭

        /// <summary>
        /// 窗口关闭
        /// </summary>        
        private void CloseWindow(Window window)
        {
            window.Close();
        }

        #endregion    
View Code

注意:最大化时存在边界溢出

处理方法:在xaml中编写触发器,当前窗口状态为 WindowState="Maximized" 时,给容器增加margin,margin左右的值为 (SystemParameters.MaximizedPrimaryScreenWidth - SystemParameters.WorkArea.Width)/ 2 ,上下也是同理。

如有更好的方法,希望留下建议。

效果图: