WPF 无边框窗口调整大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17645331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Borderless window resize
提问by Cris McLaughlin
I am designing my own custom window in WPF and I have been trying to implement the resizing functionality I have used previously in WinForms. For some reason the return value of my WndProc isn't giving me the proper result.
我正在 WPF 中设计我自己的自定义窗口,并且我一直在尝试实现我以前在 WinForms 中使用过的调整大小功能。出于某种原因,我的 WndProc 的返回值没有给我正确的结果。
I have a NativeMethods class for all my WndProc messages and results:
我的所有 WndProc 消息和结果都有一个 NativeMethods 类:
public class NativeMethods
{
public const int WM_NCHITTEST = 0x84;
public const int HTCAPTION = 2;
public const int HTLEFT = 10;
public const int HTRIGHT = 11;
public const int HTTOP = 12;
public const int HTTOPLEFT = 13;
public const int HTTOPRIGHT = 14;
public const int HTBOTTOM = 15;
public const int HTBOTTOMLEFT = 16;
public const int HTBOTTOMRIGHT = 17;
}
And here is the code behind for my window:
这是我的窗口背后的代码:
public partial class MainWindow : Window
{
const int GripSize = 16;
const int BorderSize = 7;
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
IntPtr windowHandle = new WindowInteropHelper(this).Handle;
HwndSource windowSource = HwndSource.FromHwnd(windowHandle);
windowSource.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg,
IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == NativeMethods.WM_NCHITTEST)
{
int x = lParam.ToInt32() << 16 >> 16, y = lParam.ToInt32() >> 16;
Point pos = PointFromScreen(new Point(x, y));
if (pos.X > GripSize &&
pos.X < ActualWidth - GripSize &&
pos.Y >= ActualHeight - BorderSize)
{
return (IntPtr)NativeMethods.HTBOTTOM; // This doesn't work?
}
// Top, Left, Right, Corners, Etc.
}
return IntPtr.Zero;
}
}
I expected the cursor to change to the "resize down arrow" and the resizing functionality to work as it did in my WinForms project. I have set breakpoints and the HTBOTTOM return is firing when the cursor is in the expected location. In XAML I have ResizeMode set to CanResize and the WindowStyle set to None. What am I doing wrong?
我希望光标更改为“向下调整大小箭头”,并且调整大小功能可以像在我的 WinForms 项目中一样工作。我已经设置了断点,当光标位于预期位置时,HTBOTTOM 返回正在触发。在 XAML 中,我将 ResizeMode 设置为 CanResize,将 WindowStyle 设置为 None。我究竟做错了什么?
采纳答案by Cris McLaughlin
Well this was a stupid mistake. I forgot to add handled = true;before I returned the result. Now the window is functioning as normal. As a note if you set the ResizeMode to NoResize this code won't work at all.
嗯,这是一个愚蠢的错误。我handled = true;在返回结果之前忘记添加了。现在窗口正常运行。请注意,如果您将 ResizeMode 设置为 NoResize,则此代码根本不起作用。
回答by kiran
Maybe it is simpler to assign WindowChrome.As per your comment you must be able to resize from all the sides as well as using grip.You can do all this by setting the WindowStyle to None and ResizeMode to CanResizeWithGrip or CanResize (whatever you wish to acheive)
也许分配 WindowChrome 更简单。根据您的评论,您必须能够从所有侧面调整大小以及使用手柄。您可以通过将 WindowStyle 设置为 None 并将 ResizeMode 设置为 CanResizeWithGrip 或 CanResize(无论您希望达到)
<Window x:Class="MVVMProtoType.View.Test.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Height="300" Width="300" WindowStyle="None" AllowsTransparency="False" ResizeMode="CanResizeWithGrip">
In the code behid you must set the Window Chrome for the window . You can do it like this :
在代码 behid 中,您必须为 window 设置 Window Chrome。你可以这样做:
WindowChrome.SetWindowChrome(this, new WindowChrome());
ORYou can use setter for window style like :
或者您可以将 setter 用于窗口样式,例如:
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CornerRadius="0" GlassFrameThickness="1" UseAeroCaptionButtons="False"/>
</Setter.Value>
</Setter>
MSDN link for more information
Please note WindowChrome class is a part of .NET 4.5 Framework. For.NET 4.0 users check out archive.msdn.microsoft.com/WPFShell
请注意 WindowChrome 类是 .NET 4.5 Framework 的一部分。对于 .NET 4.0 用户,请查看 archive.msdn.microsoft.com/WPFShell
回答by Fernando Aguirre
I wrote a solution in an other post, you can resize the window, you need to use .NET 4.5 or WPFShell
我在另一篇文章中写了一个解决方案,您可以调整窗口大小,您需要使用 .NET 4.5 或 WPFShell
You can also put the WindowChrome code directly on your MainWindow.xaml like this, and it works perfectly without putting a setter.
您也可以像这样将 WindowChrome 代码直接放在 MainWindow.xaml 上,无需放置 setter 即可完美运行。
<Window x:Class="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:Concursos"
mc:Ignorable="d"
Title="Concuros" Height="350" Width="525"
WindowStyle="None"
WindowState="Normal"
ResizeMode="CanResize"
>
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="0"
ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>
<Grid>
<YOUR CODE HERE
</Grid>
You can go here to view the complete post.
你可以去这里查看完整的帖子。
Here is the before and after
这是之前和之后




回答by Michael A. Allen
I also provided source code to a fully working (sizable, etc) WPF borderless window, that you might be interested in. It can be found here.
我还提供了一个完全可用的(相当大的等)WPF 无边框窗口的源代码,你可能会感兴趣。它可以在这里找到。

