如何创建一个没有边框的WPF窗口,只能通过手柄调整大小?

16 浏览
0 Comments

如何创建一个没有边框的WPF窗口,只能通过手柄调整大小?

如果在WPF的窗口上设置ResizeMode="CanResizeWithGrip",则会在右下角显示一个调整大小的手柄,如下所示:

如果还将WindowStyle="None"设置为"None",则标题栏会消失,但灰色的斜面边缘会保留,直到设置ResizeMode="NoResize"为止。不幸的是,使用这组属性设置时,调整大小的手柄也会消失。

我已经通过自定义的Style重写了WindowControlTemplate。我想自己指定窗口的边框,而且我不希望用户能够从四个方向调整窗口的大小,但我需要一个调整大小的手柄。

有人能详细说明一种满足所有这些条件的简单方法吗?

  1. 不要除了我在ControlTemplate中指定的边框之外的窗口边框。
  2. 在右下角有一个可工作的调整大小的手柄。
  3. 不要标题栏。
0
0 Comments

如何创建一个没有边框、只能通过调整大小手柄调整大小的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,就不能再通过将窗口拖动到顶部来将其捕捉。当然,你可以钩住窗口的消息并处理它。

有人问为什么无法拖动窗口,只能调整大小。这可能是因为在拖动或调整大小时,光标可能会重置,但这只是一个小问题。

0
0 Comments

如何创建一个没有边框且只能通过grip调整大小的WPF窗口?

我试图创建一个没有边框的窗口,使用WindowStyle="None",但是当我测试时,似乎在顶部出现了一个白色条。经过一些研究,它似乎是一个“调整大小的边框”,这里有一张图片(我用黄色标出来):

The Challenge

在互联网上进行了一些研究,并且有许多复杂的非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,因为我喜欢这个数字,并且因为如果您将它设置为零,调整窗口的难度会增加。

使用这段简短的代码后,结果如下图所示:

The Solution

现在,白色边框消失了,而不需要使用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()即可实现窗口拖动。

0
0 Comments

如何创建一个没有边框且只能通过grip调整大小的WPF窗口?

如果您在Window上设置AllowsTransparency属性(即使不设置任何透明度值),边框就会消失,您只能通过grip调整大小。

代码示例:


    

结果如下图所示:

![窗口截图](https://i.stack.imgur.com/5qP3U.png)

这个解决方案其实是一个巧合,我今天下午也在尝试相同的控件集合。

哇,我没想到这个方法,但是它对于在5分钟内制作自己的便笺非常方便,谢谢 🙂

然而,AllowsTransparency也有一些缺点,比如Windows无法再托管子窗口控件(比如WebBrowser),通常需要强制软件渲染,并且有报告的内存泄漏问题。请参阅下面的解决方法。

实际上,您只需要WindowStyle="None"来去除边框;AllowsTransparency只是需要它而已,并不影响边框。

这样可以去除窗口标题,但是窗体周围仍然有一个实心边框。AllowsTransparency可以去除边框。

0