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

问题描述 投票:0回答:6

如果您在 WPF

ResizeMode="CanResizeWithGrip"
上设置
Window
,则右下角会显示调整大小夹点,如下所示:

如果您还设置了

WindowStyle="None"
,标题栏会消失,但灰色斜角边缘将保留,直到您设置
ResizeMode="NoResize"
。不幸的是,通过设置这种属性组合,调整大小夹点也会消失。

我已经通过自定义

Window
覆盖了
ControlTemplate
Style
。我想自己指定窗口的边框,并且不需要用户能够从所有四个侧面调整窗口的大小,但我确实需要一个调整大小的手柄。

有人可以详细介绍一种满足所有这些标准的简单方法吗?

  1. 除了我在 Window
     中指定的边框之外,
    ControlTemplate
     上不要
    有边框。
  2. 在右下角有一个可以调整大小的手柄。
  3. 没有有标题栏。
.net wpf window controltemplate resizegrip
6个回答
198
投票
如果您在

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>

结果如下:


108
投票
我试图用

WindowStyle="None"

创建一个无边框窗口,但是当我测试它时,似乎顶部出现一个白色条,经过一些研究,它似乎是一个“调整边框大小”,这是一个图像(我在黄色):

The Challenge

经过互联网上的一些研究,以及许多困难的非xaml解决方案,我发现的所有解决方案都是C#中的代码隐藏和大量代码行,我在这里间接找到了解决方案:

最大自定义窗口失去投影效果

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

谢谢!


43
投票
虽然公认的答案非常正确,但我只想指出AllowTransparency 有一些缺点。它不允许显示子窗口控件,即 WebBrowser,并且通常会强制软件渲染,这可能会对性能产生负面影响。

不过有更好的解决办法。

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

不过我找到了一个解决方法;在窗口中,如果您将 WindowStyle 设置为 None,将 ResizeMode 设置为 NoResize(请耐心等待,完成后您仍然可以调整大小),然后确保您未选中允许透明度,您将拥有一个没有边框的静态大小窗口,并将显示浏览器控件。

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

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


6
投票
示例在这里:

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

2
投票
我在使用

WindowChrome

 工作时很难得到 @fernando-aguirre 的答案。它在我的情况下不起作用,因为我重写了 
OnSourceInitialized
 中的 
MainWindow
 并且没有调用基类方法。

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

这个问题困扰了我很长时间。


0
投票
我只是想补充一点,我成功地摆脱了顶部边框(当我切换到 WindowStyle="None" 时唯一没有消失的边框),按照 Fernando 所说的使用此代码

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


但是我不需要使用AllowsTransparency=true 设置并且它工作得很好。

© www.soinside.com 2019 - 2024. All rights reserved.