如何创建一个没有边框的WPF窗口,只能通过手柄调整大小?
如何创建一个没有边框的WPF窗口,只能通过手柄调整大小?
如果在WPF的窗口上设置ResizeMode="CanResizeWithGrip"
,则会在右下角显示一个调整大小的手柄,如下所示:
如果还将WindowStyle="None"
设置为"None",则标题栏会消失,但灰色的斜面边缘会保留,直到设置ResizeMode="NoResize"
为止。不幸的是,使用这组属性设置时,调整大小的手柄也会消失。
我已经通过自定义的Style
重写了Window
的ControlTemplate
。我想自己指定窗口的边框,而且我不希望用户能够从四个方向调整窗口的大小,但我需要一个调整大小的手柄。
有人能详细说明一种满足所有这些条件的简单方法吗?
- 不要除了我在
ControlTemplate
中指定的边框之外的窗口边框。 - 要在右下角有一个可工作的调整大小的手柄。
- 不要标题栏。
如何创建一个没有边框、只能通过调整大小手柄调整大小的WPF窗口?
在这个问题中,我们想要创建一个没有边框的窗口,可以调整大小,同时能够承载一个WebBrowser控件或指向URL的Frame控件。但是以前的解决方案有一些问题,比如不允许子窗口控件显示,并且通常会强制使用软件渲染,对性能有负面影响。
有一种更好的解决办法,我们可以将窗口的WindowStyle设置为None,ResizeMode设置为NoResize,然后确保AllowsTransparency选项未选中。这样就可以创建一个没有边框、固定大小的窗口,同时显示浏览器控件。
但是,我们可能仍然希望能够调整大小。我们可以通过调用Interop来实现:
[DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [DllImportAttribute("user32.dll")] public static extern bool ReleaseCapture(); //Attach this to the MouseDown event of your drag control to move the window in place of the title bar private void WindowDrag(object sender, MouseButtonEventArgs e) // MouseDown { ReleaseCapture(); SendMessage(new WindowInteropHelper(this).Handle, 0xA1, (IntPtr)0x2, (IntPtr)0); } //Attach this to the PreviewMousLeftButtonDown event of the grip control in the lower right corner of the form to resize the window private void WindowResize(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown { HwndSource hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource; SendMessage(hwndSource.Handle, 0x112, (IntPtr)61448, IntPtr.Zero); }
这样,我们就可以创建一个没有边框的WPF窗口,仍然可以移动和调整大小,而不会影响WebBrowser等控件的兼容性。
如果我们希望从所有方向调整大小,而不仅仅是右下角,但仍然希望没有可见的边框,应该怎么办呢?
以下是其他wParam值,只需根据需要为新的UI对象分配新的事件:private enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, TopLeft = 61444, TopRight = 61445, Bottom = 61446, BottomLeft = 61447, BottomRight = 61448, }
这对我来说很有效,但有一个例外,一旦设置了NoResize,就不能再通过将窗口拖动到顶部来将其捕捉。当然,你可以钩住窗口的消息并处理它。
有人问为什么无法拖动窗口,只能调整大小。这可能是因为在拖动或调整大小时,光标可能会重置,但这只是一个小问题。
如何创建一个没有边框且只能通过grip调整大小的WPF窗口?
我试图创建一个没有边框的窗口,使用WindowStyle="None"
,但是当我测试时,似乎在顶部出现了一个白色条。经过一些研究,它似乎是一个“调整大小的边框”,这里有一张图片(我用黄色标出来):
在互联网上进行了一些研究,并且有许多复杂的非XAML解决方案,我找到的所有解决方案都是使用C#的代码,而且代码行数很多,我在这里间接地找到了解决方案:Maximum custom window loses drop shadow effect
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="0"
ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>
注意:您需要使用.NET 4.5框架,如果您使用的是旧版本,请使用WPFShell,只需引用shell并使用Shell:WindowChrome.WindowChrome
。
我使用了Window的WindowChrome
属性,如果您使用这个属性,那个白色的“调整大小的边框”就会消失,但是您需要定义一些属性以使其正常工作。
CaptionHeight:这是标题区域(标题栏)的高度,它允许Aero捕捉、双击行为与正常标题栏相同。将其设置为0(零)以使按钮正常工作。
ResizeBorderThickness:这是窗口边缘的厚度,您可以在此处调整窗口的大小。我将其设置为5,因为我喜欢这个数字,并且因为如果您将它设置为零,调整窗口的难度会增加。
使用这段简短的代码后,结果如下图所示:
现在,白色边框消失了,而不需要使用ResizeMode="NoResize"
和AllowsTransparency="True"
,窗口还显示了阴影。
稍后,我将解释如何使用简单且简短的代码轻松地使按钮工作(我没有为按钮使用图像),我是新手,我认为我可以在codeproject上发布教程,因为在这里我找不到发布教程的地方。
也许还有其他解决方案(我知道对于像我这样的新手来说有一些困难和复杂的解决方案),但是这对于我的个人项目有效。
以下是完整的代码:
<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>
<Rectangle Fill="#D53736" HorizontalAlignment="Stretch" Height="35" VerticalAlignment="Top" PreviewMouseDown="Rectangle_PreviewMouseDown" />
<Button x:Name="Btnclose" Content="r" HorizontalAlignment="Right" VerticalAlignment="Top" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
<Button x:Name="Btnmax" Content="2" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,35,0" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
<Button x:Name="Btnmin" Content="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,70,0" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
</Grid>
谢谢!
嗯,这个解答是最简单/没有任何折衷的答案!应该得到更多的“赞”投票。我必须承认,我对它有点怀疑,特别是对于在幕后发生了什么的事情。我甚至检查了WFP树,看起来透明度没有被添加回来。即使是像“WebBrowser”这样的棘手控件也可以正常显示。我在应用程序承受很大压力时遇到了渲染冻结的问题...但是,使用这个解决方案就不会出现这个问题。我认为现在是时候退休解决方案了!
如果我正确地解释了Rectangle_PreviewMouseDown
事件的使用,这可能仍然需要使用窗口拖动的interop。
这在我的VM中看起来可能不适用于<= Win 8.1,出现了一些奇怪的结果。Windows 7和8是主要的问题,因为它们会产生愚蠢的Aero边框。
嗨,我发布了一个相关的问题,如果你有答案,我会很感激。
这绝对是最好的答案!正是所需的内容。没有折衷,没有与interop的hack。谢谢。
这很棒。解决了我的问题。我惊讶于我花了这么长时间才找到这个,但非常感谢!i2.kym-cdn.com/photos/images/newsfeed/000/117/814/…
在这里,窗口的阴影应该出现的地方,我在Windows 10(秋季创作者更新)上得到了一个奇怪的蓝色矩形闪烁一瞬间。可能是我的显卡问题。
还可以添加GlassFrameThickness="0"
来删除任何可视边框。
如果您需要在代码中设置WindowChrome,可以使用以下代码:w.SetValue(System.Windows.Shell.WindowChrome.WindowChromeProperty, new System.Windows.Shell.WindowChrome() { CaptionHeight = 0, ResizeBorderThickness = new Thickness(5) });
其中w
是Window类型的变量。
我强烈建议将CaptionHeight="35"
设置为更好的用户体验,这样可以在顶部区域移动窗口并通过双击最大化。在按钮上设置WindowChrome.IsHitTestVisibleInChrome="True"
,这样它们就可以点击了。
这个解决方案是否仍然有效?我尝试在.NET Core 3.1和Windows 10上使用它,但仍然在窗口顶部出现白色条。添加WindowChrome
标记没有效果。
弄清楚为什么在我的情况下它不起作用。在下面发布了答案。
这对我来说导致调整大小时闪烁,但是不使用它根本不会闪烁。这是否默认为软件渲染或其他什么?如果是这样,那么它是完全无用的,因为您将失去WPF的所有强大功能。
这绝对是正确的答案!如果您有多个窗口,请不要选择AllowTransperancy=true
的解决方案,性能可能会变得非常糟糕。
对于窗口移动,我不得不使用代码后台。在鼠标按下时,只需执行this.DragMove()
即可实现窗口拖动。
如何创建一个没有边框且只能通过grip调整大小的WPF窗口?
如果您在Window
上设置AllowsTransparency
属性(即使不设置任何透明度值),边框就会消失,您只能通过grip调整大小。
代码示例:
结果如下图所示:
![窗口截图](https://i.stack.imgur.com/5qP3U.png)
这个解决方案其实是一个巧合,我今天下午也在尝试相同的控件集合。
哇,我没想到这个方法,但是它对于在5分钟内制作自己的便笺非常方便,谢谢 🙂
然而,AllowsTransparency也有一些缺点,比如Windows无法再托管子窗口控件(比如WebBrowser),通常需要强制软件渲染,并且有报告的内存泄漏问题。请参阅下面的解决方法。
实际上,您只需要WindowStyle="None"来去除边框;AllowsTransparency只是需要它而已,并不影响边框。
这样可以去除窗口标题,但是窗体周围仍然有一个实心边框。AllowsTransparency可以去除边框。