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

时间:2021-08-30 07:18:50

If you set ResizeMode="CanResizeWithGrip" on a WPF Window then a resize grip is shown in the lower right corner, as below:

如果您在WPF窗口中设置ResizeMode="CanResizeWithGrip",那么在右下角显示一个缩放手柄,如下图所示:

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

If you set WindowStyle="None" as well the title bar disappears but the grey bevelled edge remains until you set ResizeMode="NoResize". Unfortunately, with this combination of properties set, the resize grip also disappears.

如果设置了WindowStyle="None",标题栏就会消失,但灰色斜角边会一直保留到设置ResizeMode="NoResize"为止。不幸的是,通过设置属性组合,调整大小的手柄也会消失。

I have overridden the Window's ControlTemplate via a custom Style. I want to specify the border of the window myself, and I don't need users to be able to resize the window from all four sides, but I do need a resize grip.

我已经通过自定义样式重写了窗口的ControlTemplate。我想自己指定窗口的边框,我不需要用户能够从四面调整窗口的大小,但是我需要一个调整大小的手柄。

Can someone detail a simple way to meet all of these criteria?

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

  1. Do not have a border on the Window apart from the one I specify myself in a ControlTemplate.
  2. 除了我在ControlTemplate中指定的边框之外,窗口上没有边框。
  3. Do have a working resize grip in the lower right corner.
  4. 在右下角有一个可调整大小的手柄。
  5. Do not have a title bar.
  6. 没有标题栏。

4 个解决方案

#1


158  

If you set the AllowsTransparency property on the Window (even without setting any transparency values) the border disappears and you can only resize via the grip.

如果您在窗口上设置了allowtransparency属性(即使没有设置任何透明值),边框就会消失,您只能通过手柄调整大小。

<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>

Result looks like:

结果看起来像:

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

#2


48  

I was trying to create a borderless window with WindowStyle="None" but when I tested it, seems that appears a white bar in the top, after some research it appears to be a "Resize border", here is an image (I remarked in yellow):

我试着用WindowStyle="None"创建一个无边框的窗口,但是当我测试它时,它的顶部似乎出现了一个白色的条形,经过一些研究,它看起来像是一个“调整边框”,这里有一个图像(我用黄色标注):

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

After some research over the internet, and lots of difficult non xaml solutions, all the solutions that I found were code behind in C# and lots of code lines, I found indirectly the solution here: Maximum custom window loses drop shadow effect

通过在互联网上的一些研究,以及大量困难的非xaml解决方案,我找到的所有解决方案都是c#中的代码和大量的代码行,我在这里间接地找到了解决方案:最大定制窗口丢失阴影效果

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

Note : You need to use .NET 4.5 framework, or if you are using an older version use WPFShell, just reference the shell and use Shell:WindowChrome.WindowChrome instead.

注意:您需要使用。net 4.5框架,或者如果您使用的是较老版本的WPFShell,只需引用shell并使用shell:WindowChrome。WindowChrome代替。

I used the WindowChrome property of Window, if you use this that white "resize border" disappears, but you need to define some properties to work correctly.

我使用了窗口的WindowChrome属性,如果您使用这个,白色的“调整大小边界”将消失,但是您需要定义一些属性来正确工作。

CaptionHeight: This is the height of the caption area (headerbar) that allows for the Aero snap, double clicking behaviour as a normal title bar does. Set this to 0 (zero) to make the buttons work.

标题高度:这是标题区域(标题栏)的高度,允许进行Aero快照,像普通标题栏一样双击。设置为0(0)以使按钮工作。

ResizeBorderThickness: This is thickness at the edge of the window which is where you can resize the window. I put to 5 because i like that number, and because if you put zero its difficult to resize the window.

resizeborderthick:这是窗口边缘的厚度,您可以在这里调整窗口的大小。我输入5,因为我喜欢这个数字,因为如果你输入0,就很难调整窗口的大小。

After using this short code the result is this:

使用这段简短的代码后,结果是:

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

And now, the white border disappeared without using ResizeMode="NoResize" and AllowsTransparency="True", also it shows a shadow in the window.

现在,白色的边框消失了,没有使用ResizeMode="NoResize"和allowstrand sparency="True",也显示了窗口中的阴影。

Later I will explain how to make to work the buttons (I didn't used images for the buttons) easily with simple and short code, Im new and i think that I can post to codeproject, because here I didn't find the place to post the tutorial.

稍后我将解释如何使用简单和简短的代码(我没有为按钮使用图像),Im new和我认为我可以发布到codeproject,因为在这里我没有找到发布教程的地方。

Maybe there is another solution (I know that there are hard and difficult solutions for noobs like me) but this works for my personal projects.

也许还有其他的解决方案(我知道对于像我这样的无名小卒来说,有困难的解决方案),但这对我的个人项目是有效的。

Here is the complete code

这是完整的代码。

<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>

Thank you!

谢谢你!

#3


34  

While the accepted answer is very true, just want to point out that AllowTransparency has some downfalls. It does not allow child window controls to show up, ie WebBrowser, and it usually forces software rendering which can have negative performance effects.

虽然公认的答案是非常正确的,但我想指出的是,允许透明度有一些下降。它不允许子窗口控件显示,即WebBrowser,并且它通常强制软件呈现,这可能有负面的性能影响。

There is a better work around though.

不过还有更好的办法。

When you want to create a window with no border that is resizeable and is able to host a WebBrowser control or a Frame control pointed to a URL you simply couldn't, the contents of said control would show empty.

当您想要创建一个窗口,该窗口没有可调整的边框,并且能够承载web浏览器控件或指向URL的框架控件时,该控件的内容将显示为空。

I found a workaround though; in the Window, if you set the WindowStyle to None, ResizeMode to NoResize (bear with me, you will still be able to resize once done) then make sure you have UNCHECKED AllowsTransparency you will have a static sized window with no border and will show the browser control.

我找到了一个变通办法;在窗口中,如果您将窗口样式设置为None,那么ResizeMode将变为NoResize(请听我说,您仍然可以在完成之后重新调整大小),然后确保您拥有未检查的allowtranence,您将拥有一个没有边框的静态大小窗口,并将显示浏览器控件。

Now, you probably still want to be able to resize right? Well we can to that with a interop call:

现在,你可能还想调整大小,对吧?我们可以通过内部通话

    [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);
    }

And voila, A WPF window with no border and still movable and resizable without losing compatibility with with controls like WebBrowser

瞧,一个没有边框的WPF窗口,仍然可以移动和调整大小,并且不会与WebBrowser之类的控件失去兼容性

#4


5  

Sample here:

示例:

<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>

#1


158  

If you set the AllowsTransparency property on the Window (even without setting any transparency values) the border disappears and you can only resize via the grip.

如果您在窗口上设置了allowtransparency属性(即使没有设置任何透明值),边框就会消失,您只能通过手柄调整大小。

<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>

Result looks like:

结果看起来像:

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

#2


48  

I was trying to create a borderless window with WindowStyle="None" but when I tested it, seems that appears a white bar in the top, after some research it appears to be a "Resize border", here is an image (I remarked in yellow):

我试着用WindowStyle="None"创建一个无边框的窗口,但是当我测试它时,它的顶部似乎出现了一个白色的条形,经过一些研究,它看起来像是一个“调整边框”,这里有一个图像(我用黄色标注):

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

After some research over the internet, and lots of difficult non xaml solutions, all the solutions that I found were code behind in C# and lots of code lines, I found indirectly the solution here: Maximum custom window loses drop shadow effect

通过在互联网上的一些研究,以及大量困难的非xaml解决方案,我找到的所有解决方案都是c#中的代码和大量的代码行,我在这里间接地找到了解决方案:最大定制窗口丢失阴影效果

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

Note : You need to use .NET 4.5 framework, or if you are using an older version use WPFShell, just reference the shell and use Shell:WindowChrome.WindowChrome instead.

注意:您需要使用。net 4.5框架,或者如果您使用的是较老版本的WPFShell,只需引用shell并使用shell:WindowChrome。WindowChrome代替。

I used the WindowChrome property of Window, if you use this that white "resize border" disappears, but you need to define some properties to work correctly.

我使用了窗口的WindowChrome属性,如果您使用这个,白色的“调整大小边界”将消失,但是您需要定义一些属性来正确工作。

CaptionHeight: This is the height of the caption area (headerbar) that allows for the Aero snap, double clicking behaviour as a normal title bar does. Set this to 0 (zero) to make the buttons work.

标题高度:这是标题区域(标题栏)的高度,允许进行Aero快照,像普通标题栏一样双击。设置为0(0)以使按钮工作。

ResizeBorderThickness: This is thickness at the edge of the window which is where you can resize the window. I put to 5 because i like that number, and because if you put zero its difficult to resize the window.

resizeborderthick:这是窗口边缘的厚度,您可以在这里调整窗口的大小。我输入5,因为我喜欢这个数字,因为如果你输入0,就很难调整窗口的大小。

After using this short code the result is this:

使用这段简短的代码后,结果是:

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

And now, the white border disappeared without using ResizeMode="NoResize" and AllowsTransparency="True", also it shows a shadow in the window.

现在,白色的边框消失了,没有使用ResizeMode="NoResize"和allowstrand sparency="True",也显示了窗口中的阴影。

Later I will explain how to make to work the buttons (I didn't used images for the buttons) easily with simple and short code, Im new and i think that I can post to codeproject, because here I didn't find the place to post the tutorial.

稍后我将解释如何使用简单和简短的代码(我没有为按钮使用图像),Im new和我认为我可以发布到codeproject,因为在这里我没有找到发布教程的地方。

Maybe there is another solution (I know that there are hard and difficult solutions for noobs like me) but this works for my personal projects.

也许还有其他的解决方案(我知道对于像我这样的无名小卒来说,有困难的解决方案),但这对我的个人项目是有效的。

Here is the complete code

这是完整的代码。

<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>

Thank you!

谢谢你!

#3


34  

While the accepted answer is very true, just want to point out that AllowTransparency has some downfalls. It does not allow child window controls to show up, ie WebBrowser, and it usually forces software rendering which can have negative performance effects.

虽然公认的答案是非常正确的,但我想指出的是,允许透明度有一些下降。它不允许子窗口控件显示,即WebBrowser,并且它通常强制软件呈现,这可能有负面的性能影响。

There is a better work around though.

不过还有更好的办法。

When you want to create a window with no border that is resizeable and is able to host a WebBrowser control or a Frame control pointed to a URL you simply couldn't, the contents of said control would show empty.

当您想要创建一个窗口,该窗口没有可调整的边框,并且能够承载web浏览器控件或指向URL的框架控件时,该控件的内容将显示为空。

I found a workaround though; in the Window, if you set the WindowStyle to None, ResizeMode to NoResize (bear with me, you will still be able to resize once done) then make sure you have UNCHECKED AllowsTransparency you will have a static sized window with no border and will show the browser control.

我找到了一个变通办法;在窗口中,如果您将窗口样式设置为None,那么ResizeMode将变为NoResize(请听我说,您仍然可以在完成之后重新调整大小),然后确保您拥有未检查的allowtranence,您将拥有一个没有边框的静态大小窗口,并将显示浏览器控件。

Now, you probably still want to be able to resize right? Well we can to that with a interop call:

现在,你可能还想调整大小,对吧?我们可以通过内部通话

    [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);
    }

And voila, A WPF window with no border and still movable and resizable without losing compatibility with with controls like WebBrowser

瞧,一个没有边框的WPF窗口,仍然可以移动和调整大小,并且不会与WebBrowser之类的控件失去兼容性

#4


5  

Sample here:

示例:

<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>