# wpfMainWindow **Repository Path**: zxjlxc/wpf-main-window ## Basic Information - **Project Name**: wpfMainWindow - **Description**: 设置主窗体的几种方法 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-11-08 - **Last Updated**: 2023-12-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 一、概述 怎样处理主界面的样式 # 二、解决方案 ## 1.直接去掉窗口的边框和标题栏 1、先写一个border置顶 ![](./README/main1.PNG) 效果 ![](./README/main2.PNG) 2、去掉标题栏 ```C# WindowStyle="None" ``` 效果 ![](./README/main3.PNG) 3、去掉四周的拖拽 ```C# AllowsTransparency="True" ``` 效果 ![](./README/main4.PNG) 4、给窗体添加可以调整大小属性 ```c# ResizeMode="CanResizeWithGrip" ``` 效果 ![](./README/main5.PNG) 5、给红色的border添加鼠标拖拽事件 ```c# MouseMove="Border_MouseMove" ``` ```c# private void Border_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { DragMove(); } } ``` 6、最小化、最大化、关闭 ![](./README/main6.PNG) ![](./README/main7.PNG) ```C# private void MinTextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.WindowState = WindowState.Minimized; } private void MaxTextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (this.WindowState == WindowState.Maximized) { this.WindowState = WindowState.Normal; } else this.WindowState = WindowState.Maximized; } private void CloseTextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.Close(); } ``` 改进使用矢量图 ```C# ``` 效果 ![](./README/main8.PNG) 7、重写右下角的拖拽图标 如果感觉右下角的图标比较丑 ![](./README/main9.PNG) Thumb 类,表示可由用户拖动的控件。 首先删除窗口的属性,去掉这一句 ```C# ResizeMode="CanResizeWithGrip" ``` 然后 ```C# ``` ```C# private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) { Width += e.HorizontalChange; Height += e.VerticalChange; } ``` 效果,背景色设置为透明了,所以看不到 ![](./README/main10.PNG) ## 2、使用WindowChrome ### ①基本内容 一个标准的Window的基本构成,主要由非工作区(non-client area)和工作区(client area)组成。 标准window中除client之外的部分称为non-client area,通常称之为chrome,它提供了标准的窗口功能和行为,具体包含以下部分:边框、阴影、标题栏、Icon、标题、SystemMenu、最小化、最大化、还原、关闭、大小调整手柄。 当Window处于最大化状态时标题栏比较矮。在100% DPI时标题栏的高度为30像素,最大化时变为22像素,这时候右上角的几个按钮缩小了,其它元素的Margin也减少了一些。 ### ②Window的大小 最后要说的是Window的大小。Window的实际大小并不是表面上看到的大小。 如下Window定义的大小为450,800,实时可视化树显示网格abc的大小是785.6,412.8。高度可能是因为标题栏,但宽度可以肯定是变小了。 ![](./README/main11.PNG) 如果将Window设置为启动位置在左上角 ```C# WindowStartupLocation="Manual" Top="0" Left="0" ``` 效果(可以看到左边有间隔,上边没有) ![](./README/main12.PNG) 通过[Inspect](https://docs.microsoft.com/zh-cn/windows/desktop/WinAuto/inspect-objects)看到的Window如下,黄色边框为它的实际范围: ![](./README/main13.PNG) 可以看到系统理解的Window范围和我们看到的不同,这是Window设计的问题,有几个值用于计算chrome的尺寸: ![](./README/main14.PNG) 在有标题的标准Window,chrome的顶部尺寸为SM_CYFRAME + SM_CXPADDEDBORDER + SM_CYCAPTION = 31,左右两边尺寸为SM_CXFRAME + SM_CXPADDEDBORDER = 8,底部尺寸为SM_CYFRAME + SM_CXPADDEDBORDER = 8。 最大化情况下Border和ResizeBorder都超出屏幕范围而且被隐藏了,所以Window的尺寸会超过显示器工作区的尺寸,这时候标题栏也会相应地变矮。在Windows 10,系统认为Window有4像素的ResizeBorder,但因为Windows 10是窄边框设计,而且在普通状态下和最大化状态下的标题栏高度还不一样,导致用UISpy观察Window和我们看到的Window不一致,也常常导致位置计算上的问题。 注意,上面的尺寸计算都是基于100 % DPI,在不同DPI的情况下还需要将DPI的值纳入计算。 ### ③案例 目的:尽量保存原窗口属性,又可以使工作区(client)覆盖非工作区(non-client、chrome)。 1.我认为是把WindowChrome写出来,并且为空,所以之前的一些设置没有了,这样就使得工作区覆盖到了非工作区。同时移动、最小化、最大化、关闭功能都还在,只是看不到。 ```C# ``` 效果 ![](./README/main15.PNG) 2.我认为是重新写真实的工作区,使他为空,这样我们可以观察一切。 ```C# ``` 效果(此时我们可以清楚的看到布局) ![](./README/main16.PNG) 3.关闭按钮没有贴近右边,我们把左右下设置为非工作区的边界 ```c# NonClientFrameEdges="Left,Bottom,Right" ``` 效果 ![](./README/main17.PNG) 4.但是现在窗口最大化时标题栏和里面的按钮就被压缩变短了,如下图 ![](./README/main18.PNG) 可以把上边的厚度改大一些,不让原始的工作区挤压到标题栏 ```c# GlassFrameThickness="0,64,0,0" ``` 效果 ![](./README/main19.PNG) 最大化时(可以看到也没有被挤压) ![](./README/main20.PNG) 到这里,就实现了工作区可以覆盖非工作区,也保留了基本属性。 ## 3、简单方便的方法 前面两种方案各有优缺。第一种比较灵活,但是没有了基本属性。第二种保留了很多基本属性,但是不够灵活,比如想要实现标题栏按钮的一些效果比较麻烦。 看到有人说两种结合比较简单方便。 1.使用 ```c# WindowStyle="None" ``` 去掉样式(没有了按钮,但是周边还可以拖拽),再使用 ```c# ``` 此时的效果是有基本属性(周边可以拖拽、窗体可以移动),工作区也覆盖了非工作区,也没有标题栏按钮,可以灵活的自定义各种效果。 注意:给在WindowChrome区域的元素添加WindowChrome.IsHitTestVisibleInChrome="True"附加属性。这样WindowChrome区域的元素就可以交互了。 效果 ![](./README/main21.PNG) ## 4、效果最好的应该是2 可以参考项目WpfAppTest 建议使用这样的 ``` ```