第一步:基本实现

  • 添加Window的Style定义,并设置WindowChrome.WindowChrome属性;
  • 设置WindowChrome标题栏:
  1. CaptionHeight——主要用于拖动有效区;
  2. GlassFrameThickness——影响标题栏系统按钮显示,0表示不使用系统按钮【后面介绍】,-1表示用的系统默认值,如下示例则表示标题栏高度30;
  3. 自定义窗体Title

第二步:优化边界处理

  1. 方法1:模板添加最大化触发器,设置最大化时,内部布局Margin设为8
  2. 方法2:模板添加最大化触发器,设置最大化时,限制布局最大化的宽高最大值

第三步:完全自定义标题栏【即,不使用系统的操作按钮】

  1. 初步操作类似第一步,其中将GlassFrameThickness设置为0
  2. 在内容定义部分添加自定义的标题栏,添加操作按钮,并设置按钮属性WindowChrome.IsHitTestVisibleInChrome="True"
  3. 如果不设置WindowChrome.IsHitTestVisibleInChrome,则由于我们之前设置CaptionHeight,则这个区域内,按钮将失效。
  4. 但是,也不能将整个标题栏布局设置这个属性,那样会完全覆盖系统标题栏的操作,如拖动效果,即CaptionHeight设置的那个区域
    <Window x:Class="WindowChrome自定义窗体样式.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:WindowChrome自定义窗体样式"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800"
    FontWeight="ExtraLight" ResizeMode="CanResize" WindowStartupLocation="CenterScreen"
    WindowStyle="None" AllowsTransparency="True" Background="{x:Null}">
    <Window.Resources>
    <Style x:Key="btn_nap" TargetType="{x:Type Button}">
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="Button">
    <Border Background="{TemplateBinding Background}">
    <ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"></ContentPresenter>
    </Border>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    <Setter Property="FontSize" Value="18"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Background" Value="Transparent"/>
    <Style.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
    <Setter Property="Opacity" Value="0.7"/>
    </Trigger>
    <!--<Trigger Property="IsMouseOver" Value="False">
    <Setter Property="Background" Value="#EEF0F5"/>
    </Trigger>-->
    </Style.Triggers>
    </Style>
    </Window.Resources>
    <WindowChrome.WindowChrome>
    <WindowChrome CaptionHeight="35" UseAeroCaptionButtons="False" x:Name="windowChrome" CornerRadius="0" GlassFrameThickness="0"/>
    </WindowChrome.WindowChrome>
    <Grid>
    <Grid.RowDefinitions>
    <RowDefinition Height="35"/>
    <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid Background="#3C6AB1">
    <TextBlock x:Name="lblTitle" Text="测试" Foreground="White" FontSize="14" Margin="10 0 0 0" VerticalAlignment="Center"/>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <Button WindowChrome.IsHitTestVisibleInChrome="True" Name="button_MiniSize" Content="─" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/>
    <Button WindowChrome.IsHitTestVisibleInChrome="True" Name="button_MaxSize" Content="☐" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/>
    <Button WindowChrome.IsHitTestVisibleInChrome="True" x:Name="btn_Close" Content="✕" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/>
    </StackPanel>
    </Grid>
    <Grid Grid.Row="1" Background="LightBlue"> </Grid>
    </Grid>
    </Window>
     public partial class MainWindow : Window
    {
    public MainWindow()
    {
    InitializeComponent();
    this.button_MiniSize.Click += Btn_Min_Click;
    this.button_MaxSize.Click += Btn_Max_Click;
    this.btn_Close.Click += Btn_Close_Click;
    //CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, (_, __) => { SystemCommands.CloseWindow(this); }));
    //CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, (_, __) => { SystemCommands.MinimizeWindow(this); }));
    //CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, (_, __) => { SystemCommands.MaximizeWindow(this); }));
    //CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, (_, __) => { SystemCommands.RestoreWindow(this); }));
    //CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, ShowSystemMenu));
    }
    //private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e)
    //{
    // var element = e.OriginalSource as FrameworkElement;
    // if (element == null)
    // return; // var position = WindowState == WindowState.Maximized ? new Point(0, element.ActualHeight)
    // : new Point(Left + BorderThickness.Left, element.ActualHeight + Top + BorderThickness.Top);
    // position = element.TransformToAncestor(this).Transform(position);
    // SystemCommands.ShowSystemMenu(this, position);
    //}
    private void Btn_Close_Click(object sender, RoutedEventArgs e)
    {
    this.Close();
    } private void Btn_Max_Click(object sender, RoutedEventArgs e)
    {
    this.WindowState = WindowState.Maximized == this.WindowState ? WindowState.Normal : WindowState.Maximized;
    } private void Btn_Min_Click(object sender, RoutedEventArgs e)
    {
    this.WindowState = WindowState.Minimized;
    }
    }

WPF使用WindowChrome自定义标题栏的更多相关文章

  1. [WPF]使用WindowChrome自定义Window Style

    1. 前言 做了WPF开发多年,一直未曾自己实现一个自定义Window Style,无论是<WPF编程宝典>或是各种博客都建议使用WindowStyle="None" ...

  2. WPF 使用WindowChrome自定义窗体 保留原生窗体特性

    本文大幅度借鉴dino.c大佬的文章 https://www.cnblogs.com/dino623/p/uielements_of_window.html https://www.cnblogs.c ...

  3. WPF中自定义标题栏时窗体最大化处理之WindowChrome

    注意: 本文方法基础是WindowChrome,而WindowChrome在.NET Framework 4.5之后才集成发布的.见:WindowChrome Class 在.NET Framewor ...

  4. [WPF自定义控件]使用WindowChrome自定义Window Style

    1. 为什么要自定义Window 对稍微有点规模的桌面软件来说自定义的Window几乎是标配了,一来设计师总是克制不住自己想想软件更个性化,为了UI的和谐修改Window也是必要的:二来多一行的空间可 ...

  5. [WPF 自定义控件]使用WindowChrome自定义RibbonWindow

    1. 为什么要自定义RibbonWindow 自定义Window有可能是设计或功能上的要求,可以是非必要的,而自定义RibbonWindow则不一样: 如果程序使用了自定义样式的Window,为了统一 ...

  6. [WPF自定义控件库]使用WindowChrome自定义RibbonWindow

    原文:[WPF自定义控件库]使用WindowChrome自定义RibbonWindow 1. 为什么要自定义RibbonWindow 自定义Window有可能是设计或功能上的要求,可以是非必要的,而自 ...

  7. [WPF自定义控件]?使用WindowChrome自定义Window Style

    原文:[WPF自定义控件]?使用WindowChrome自定义Window Style 1. 为什么要自定义Window 对稍微有点规模的桌面软件来说自定义的Window几乎是标配了,一来设计师总是克 ...

  8. WPF 自定义标题栏 自定义菜单栏

    自定义标题栏 自定义列表,可以直接修改WPF中的ListBox模板,也用这样类似的效果.但是ListBox是不能设置默认选中状态的. 而我们需要一些复杂的UI效果,还是直接自定义控件来的快 GitHu ...

  9. WPF自定义界面WindowChrome

    WPF自定义界面WindowChrome 默认WPF的界面其实也还行,就是满足不了日渐增长的需求,界面还是需要有更高的自定义程度,包括标题栏也要能够塞下更多的操作控件. 默认窗口介绍 新建WPF项目, ...

  10. UWP中实现自定义标题栏

    UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http ...

随机推荐

  1. 为什么NoSQL数据库这么受欢迎?

    大数据时代,NoSQL数据库是企业构建数据能力的核心工具之一.近期,在2022腾讯全球数字生态大会NoSQL数据库专场上,腾讯云发布了多项NoSQL产品能力升级,并重点讲解了其背后的自研技术要点及实现 ...

  2. Socket爬虫:Python版

    简述:较为底层的爬虫实现,用于了解爬虫底层实现的具体流程,现在各种好用的爬虫库(如requests,httpx...等)都是基于此进行封装的. PS:本文只作为实现请求的代码记录,基础部分不做过多阐述 ...

  3. MSIC总结取证分析——日志分析

    MSIC总结取证分析 一.日志分析: 1.常见日志分析类型: 2.常见一些考点: (1)还原特定IP攻击手段(SQL注入.暴力破解.命令执行等),或还原最初攻击时间: (2)寻找flag或者特定文件解 ...

  4. 【Java复健指南15】链表LinkedList及其说明

    链表LinkedList by Java 之前有写过一些记录(引用),但是忘了乱了,现在重新梳理一遍 链表是Java中List接口的一种实现 定义(引用) 链表(linked list)是一种物理存储 ...

  5. [NOIP2017 普及组]跳房子 【题解】

    题目背景 NOIP2017 普及组 T4 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 \(n ...

  6. OpenMP 线程同步 Construct 实现原理以及源码分析(下)

    OpenMP 线程同步 Construct 实现原理以及源码分析(下) 前言 在上面文章当中我们主要分析了 flush, critical, master 这三个 construct 的实现原理.在本 ...

  7. C# 学习async/await(个人理解)

    await : 等待的意思 async:异步(非同步) 当我们方法内部   存在await的时候,就返回出去 执行下一步 ,等await后面的方法执行完毕 在执行await下面的方法 一.我们先看正常 ...

  8. LeetCode_387. 字符串中的第一个唯一字符

    写在前面 原文地址:https://leetcode.cn/problems/first-unique-character-in-a-string/ 难度:简单 题目 给定一个字符串 s ,找到 它的 ...

  9. 【Oculus Interaction SDK】(十二)Meta Quest 如何开启透视(Passthrough)

    前言 前段时间 Oculus 的 SDK 频繁更新,很多已有的教程都不再适用于现在的版本了.本系列文章的主要目的是记录现版本常见功能的实现方法,便于自己后续开发.当然,不排除我文章刚写完 SDK 又变 ...

  10. TreeMap排序Comparator()重写

    package map_;import java.util.Comparator;import java.util.TreeMap;/* * @author YAM */public class Tr ...