WPF无边界窗口问题:Aero Snap&最大化 [英] WPF Borderless Window issues: Aero Snap & Maximizing

查看:84
本文介绍了WPF无边界窗口问题:Aero Snap&最大化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过在XAML中设置以下窗口属性来创建无边界WPF窗口:

I've created a borderless WPF window by setting the following window properties in XAML:

... WindowStyle="None" AllowsTransparency="True" ...

这会导致许多问题:

1)已解决::它不再具有任何内置的调整大小功能

1) Resolved: It no longer has any built-in resize functionality

2)已解决::它不再具有任何内置的拖动功能

2) Resolved: It no longer has any built-in drag functionality

3)已解决:没有顶部工具栏,它将不再具有最小化/最大化/还原/关闭按钮

3) Resolved: Without the top toolbar, it no longer has minimize/maximize/restore/close buttons

4)已解决:通过航空捕捉或设置最大化WindowState防止其被捕捉。

4) Resolved: Maximizing via aero snap or setting WindowState prevents it from unsnapping.

5)通过航空捕捉或设置最大化最大化WindowState将整个屏幕作为边界,与Windows工具栏重叠。

5) Maximizing via aero snap or setting WindowState will use the whole screen as the boundary, overlapping the windows toolbar.

6)通过航空快照或设置WindowState最大化,似乎包含-7的边距,给了windo w每边7个像素都超出了窗口的边缘。

6) Maximizing via aero snap or setting WindowState seems to include a -7 margin, giving the window 7 pixels on each side that are beyond the edges of the window.

1-3通过制作xaml窗口模板来解决。我使用不可见的矩形作为句柄区域,其后的一些代码通过重写OnApplyTemplate()来通过user32.dll SendMessage(...)附加功能,以调整大小/移动/最小化/最大化/恢复/关闭。

1-3 were solved by making a xaml window template. I used invisible rectangles as handle regions, and some code behind that was applied via overriding OnApplyTemplate() to attach functionality via user32.dll SendMessage(...) for resize/move/minimize/maximize/restore/close.

我找到了#4的答案在这里

我尝试通过WndProc截取最大化消息并手动设置大小/位置来解决5-6,但这存在将RestoreRegion覆盖为最大化大小/位置的问题,恢复窗口的能力。

I tried solving 5-6 by intercepting the maximize message via WndProc and setting the size/position manually, but this had the issue of overwriting the RestoreRegion to the maximized size/position, removing the ability to restore the window.

真正奇怪的是,将窗口的大小从顶部边框调整到屏幕顶部会触发空气动力学高度捕捉,而没有任何问题。

What's really odd is that resizing the window from the top border to the top of the screen triggers the aero full height snap just fine, with no issues at all.

所以,我走了很长一段路,但是5-6仍然是个问题...有没有办法手动指定最大化区域?或者,是否可以在不影响restoreregion属性的情况下设置窗口大小?

So, I've come a long way, but 5-6 is still an issue... is there a way to manually specify the maximize region? Or, is there a way to set the window size without affecting the restoreregion property?

推荐答案


最简单的完整解决方案

Easiest Full Solution

您好,以下解决方案以最简单的方式解决了您的问题中详述的所有问题,并在使用WPF和最新版本的C#语言和.NET框架的Windows 10上运行。这是截至2017年3月15日。请让我知道它是否停止工作。

Hello, The following solution fixes all of the issues detailed in your question in the simplest manner possible, and works on Windows 10 using WPF and the latest version of the C# language and .NET framework. This is as of 3/15/2017. Please let me know if it stops working.

步骤1:要解决您的<$ c $中的问题1、2和4。 c><窗口...> < / Window> 标记,粘贴到顶部或底部:

Step 1: To address issues 1, 2, and 4, within your <Window ... > </Window> tags in the XAML of your application, paste this in, at the top or bottom:

<WindowChrome.WindowChrome>
    <WindowChrome CaptionHeight="35"/>
<WindowChrome.WindowChrome>

CaptionHeight 是窗口的期望高度拖动区域。

CaptionHeight is the desired height of your window dragging area.

步骤2:要解决问题3,您需要创建标题栏和标题以及窗口控件。为此,您只需要为每个所需的标题栏元素提供一个verticalAlignment of Top,或者将它们放置在其VerticalAlignment设置为Top的网格中,这将对所有元素都进行,但是请确保它们的高度不从第1步开始,大于XAML中声明的 WindowChrome 元素上的 CaptionHeight 属性。对于所有按钮,必须为其分配其容器,或为其属性 WindowChrome.IsHitTestVisibleInChrome = True 。这是一个例子:

Step 2: To address issue 3, you need to create your title bar and caption as well as the window controls. To do this, you simply need to give the desired title bar elements each a VerticalAlignment of Top, or put them into a grid with it's VerticalAlignment set to Top, which will do it for all of them, but make sure that their heights are not greater than the CaptionHeight property on the WindowChrome element declared in the XAML, from step 1. For all the buttons, you must assign them, or their container, the property WindowChrome.IsHitTestVisibleInChrome="True". Here is an example:

<Grid VerticalAlignment="Top" Background="White" Name="TitleBar" Height="35">
    <Label Content="Borderless Window Test" VerticalAlignment="Center" HorizontalAlignment="Left"/>
    <StackPanel WindowChrome.IsHitTestVisibleInChrome="True" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal" Name="WindowControls">
        <Button Height="35" Width="35" Content="-" Padding="0" Name="MinimizeButton"/>
        <Button Height="35" Width="35" Content="+" Padding="0" Name="MaximizeButton"/>
        <Button Height="35" Width="35" Content="x" Padding="0" Name="CloseButton"/>
    </StackPanel>
</Grid>

现在,在 MainWindow内向窗口控制按钮添加适当的功能()代码的构造函数,即应用程序的C#源代码,将以下内容粘贴到调用 InitializeComponent();

Now, to add proper functionality to the window control buttons, within the MainWindow() constructor of your codebehind, the C# source code of your application, paste the following in, after the call to InitializeComponent();:

CloseButton.Click += (s, e) => Close();
MaximizeButton.Click += (s, e) => WindowState = WindowState == WindowState.Normal ? WindowState.Maximized : WindowState.Normal;
MinimizeButton.Click += (s, e) => WindowState = WindowState.Minimized;

步骤3:要解决问题5和6,您需要挂钩进入WmGetMinMaxInfo。为此,请转至您的代码隐藏,然后将所有 Pastebin 中的内容复制并粘贴到您的Window类中。现在,在您的 MainWindow()构造函数中,粘贴:

Step 3: To address issues 5 and 6, you need to hook into WmGetMinMaxInfo. To do this, go to your codebehind, then copy and paste everything from this Pastebin into your Window class. Now, within your MainWindow() constructor, paste:

SourceInitialized += (s, e) =>
{
    IntPtr handle = (new WindowInteropHelper(this)).Handle;
    HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(WindowProc));
};

通过 Project>在文件菜单中添加引用,请确保具有以下引用:

Via Project > Add References in the file menu, be sure to have references to:

System.Management
System.Windows.Interop
System.Security.Principal
System.Runtime.InteropServices
Microsoft.Win32

最好的检查方法是单击左上角的 Assemblies 标签,然后选择 Framework ,然后使用窗口右上角的搜索框。现在,将所有这些使用(命名空间)添加到代码的顶部:

The best way to check is to click on the Assemblies tab in the top left, then select Framework, then use the search box in the top right corner of the window. Now add all of these usings (namespaces) to the top of your codebehind:

using System.Management;
using System.Windows.Interop;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;

这应该涵盖了所有内容。希望对您有所帮助!

That should cover everything. I hope this helps!

这篇关于WPF无边界窗口问题:Aero Snap&amp;最大化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆