如何创建一个无边框的WPF窗口,而该边框只能通过夹点进行调整?


94

如果设置ResizeMode="CanResizeWithGrip"为WPF,Window则调整大小的夹点将显示在右下角,如下所示:

如果您还进行了设置WindowStyle="None",则标题栏将消失,但灰色斜角边缘将保留直到您进行设置ResizeMode="NoResize"。不幸的是,通过设置这些属性组合,调整大小的抓地力也消失了。

我已经覆盖了WindowControlTemplate通过自定义Style。我想自己指定窗口的边框,我不需要用户能够从所有四个侧面调整窗口的大小,但是我确实需要调整大小。

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

  1. Window除了在边框中指定自己的边框之外,没有边框ControlTemplate
  2. 在右下角工作调整大小的抓地力。
  3. 没有标题栏。

3
请注意,Allowtransperency会造成内存泄漏。因此,请避免使用它。请参考social.msdn.microsoft.com/Forums/en/wpf/thread/…–
Dipesh Bhatt

1
@DipeshBhatt我在您提供的链接中找不到对该要求的任何解释。也许您的意思是发布链接social.msdn.microsoft.com/Forums/vstudio/en-US/…–
itsho

尽管我已将窗口样式设置为“无”,但我面对的是顶部的灰色边缘。ResizeMode =“ NoResize”解决了我的问题。
Surendra Shrestha

Answers:


180

如果将AllowsTransparency属性设置为Window(即使未设置任何透明度值),边框也会消失,并且只能通过夹点调整大小。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="640" Height="480" 
    WindowStyle="None"
    AllowsTransparency="True"
    ResizeMode="CanResizeWithGrip">

    <!-- Content -->

</Window>

结果如下:


纯粹的fl幸,我知道这一点-今天下午,我在自己的控制装置上演奏。:)
ZombieSheep 2009年

2
哇,我不希望这样,但它是化妆你自己的便利贴,票据功能于5分钟完全派上用场,谢谢:)
托马什卡夫卡

4
但是,AllowTransparency有几个缺点,Windows无法再托管子窗口控件,例如WebBrowser(通常强制软件渲染)已报告内存泄漏。请参阅下面的解决方法。
2014年

您只需要WindowStyle =“ None”即可摆脱边框;AllowsTransparency只发生在需要它,但不影响边界..
Grault

2
@Grault thats摆脱了窗口标题,但是表单周围仍然有一个实心边框。AllowsTransparency摆脱了边界。
2015年

78

我试图创建一个无边界的窗口, WindowStyle="None"但是当我对其进行测试时,似乎在顶部出现了一个白色的条,经过一番研究,它看起来像是“调整边框”,这是一张图片(我用黄色标记):

挑战

经过Internet上的一些研究,以及许多困难的非xaml解决方案之后,我发现的所有解决方案都是C#和大量代码行背后的代码,我在这里间接找到了解决方案:最大的自定义窗口会失去阴影效果

<WindowChrome.WindowChrome>
    <WindowChrome 
        CaptionHeight="0"
        ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>

注意 :您需要使用.NET 4.5框架,或者如果您使用的是旧版本,请使用WPFShell,只需引用该Shell并使用Shell:WindowChrome.WindowChrome

我使用了WindowChromeWindow 的属性,如果使用此属性,则白色的“调整边框”消失了,但是您需要定义一些属性才能正常工作。

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>

谢谢!


3
好吧,这个荣誉!到目前为止,这是该线程最简单/没有权衡的答案!应该获得更多的“赞成”票。我必须承认我对此持怀疑态度,尤其是对于幕后发生的事情。我什至检查了WFP树,并确定没有添加透明度。甚至“ WebBrowser”之类的棘手控件也可以正常显示。当应用程序承受很大压力时,使用透明性时出现了渲染冻结问题。我认为可能是时候退出@Wobbles解决方案了!
VeV '16

1
如果我Rectangle_PreviewMouseDown正确地解释了事件的使用,看起来这可能仍需要互操作才能进行窗口拖动。
摆动

在<= Win 8.1中,这可能不起作用,在我的VM中看到了一些奇怪的结果。Windows 7和8是主要顾虑,因为它们会执行愚蠢的Aero边界操作。
摆动

谢谢您的回覆
Fernando Aguirre

嗨@FernandoAguirre,我发布了这个相关问题,如果您有答案,将不胜感激。
sampathsris

39

尽管公认的答案是正确的,但只想指出AllowTransparency有一些缺点。它不允许显示子窗口控件,即WebBrowser,通常会强制进行软件渲染,这可能会对性能产生负面影响。

虽然有更好的解决方法。

当您要创建一个无边框且可调整大小的窗口,并且能够承载指向您根本无法指向的URL的WebBrowser控件或Frame控件时,该控件的内容将显示为空。

我找到了解决方法;在窗口中,如果将WindowStyle设置为None,将ResizeMode设置为NoResize(对我来说,一旦完成,您仍然可以调整大小),然后确保您具有UNCHECKED AllowsTransparency,您将拥有一个无边框的静态大小的窗口并显示浏览器控件。

现在,您可能仍然希望能够调整大小吗?好吧,我们可以通过互操作来做到这一点:

    [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之类控件的兼容性


如果要从各个方向调整大小,而不仅是右下角,但仍不希望看到边框,该怎么办?
丹尼尔(Daniel)

6
以下是其他wParam值,只需根据需要使用这些值将新事件分配给新UI对象private enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, TopLeft = 61444, TopRight = 61445, Bottom = 61446, BottomLeft = 61447, BottomRight = 61448, }
摇晃

这对我非常有用,但有一个例外,尽管一旦有了NoResize,就无法再通过将其拖动到顶部来捕捉窗口。
CJK 2015年

2
@CJK是的,但毫无疑问,您也可以挂钩Windows消息并进行处理。
2015年

我无法拖动窗口。知道为什么吗?(调整大小就像一种魅力)
Li3ro

5

这里的示例:

<Style TargetType="Window" x:Key="DialogWindow">
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="ResizeMode" Value="CanResizeWithGrip"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Border BorderBrush="Black" BorderThickness="3" CornerRadius="10" Height="{TemplateBinding Height}"
                            Width="{TemplateBinding Width}" Background="Gray">
                        <DockPanel>
                            <Grid DockPanel.Dock="Top">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition></ColumnDefinition>
                                    <ColumnDefinition Width="50"/>
                                </Grid.ColumnDefinitions>
                                <Label Height="35" Grid.ColumnSpan="2"
                                       x:Name="PART_WindowHeader"                                            
                                       HorizontalAlignment="Stretch" 
                                       VerticalAlignment="Stretch"/>
                                <Button Width="15" Height="15" Content="x" Grid.Column="1" x:Name="PART_CloseButton"/>
                            </Grid>
                            <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                                        Background="LightBlue" CornerRadius="0,0,10,10" 
                                        Grid.ColumnSpan="2"
                                        Grid.RowSpan="2">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition/>
                                        <ColumnDefinition Width="20"/>
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*"/>
                                        <RowDefinition Height="20"></RowDefinition>
                                    </Grid.RowDefinitions>
                                    <ResizeGrip Width="10" Height="10" Grid.Column="1" VerticalAlignment="Bottom" Grid.Row="1"/>
                                </Grid>
                            </Border>
                        </DockPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

23
您应该简要说明代码的工作原理。
M456

0

我很难通过@ fernando-aguirre来获得答案WindowChrome。在我的情况下,它不起作用,因为我覆盖OnSourceInitializedMainWindow且未调用基类方法。

protected override void OnSourceInitialized(EventArgs e)
{
    ViewModel.Initialize(this);
    base.OnSourceInitialized(e); // <== Need to call this!
}

这使我困扰了很长时间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.