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

时间:2009-03-04 16:17:53

标签: .net wpf window controltemplate resizegrip

如果您在WPF ResizeMode="CanResizeWithGrip"上设置Window,则会在右下角显示调整大小的抓地力,如下所示:

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

我已通过自定义Window覆盖了ControlTemplate的{​​{1}}。我想自己指定窗口的边框,我不需要用户能够从四面调整窗口大小,但我确实需要调整大小。

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

  1. 不要Style上设置一个边框,而不是我在Window中指定的边框。
  2. 在右下角有一个有效的调整大小手柄。
  3. 不要有标题栏。

5 个答案:

答案 0 :(得分:168)

如果您在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>

结果如下:

  

答案 1 :(得分:59)

我正在尝试使用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属性,如果你使用它,那么白色的“resize border”会消失,但你需要定义一些属性才能正常工作。

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>

谢谢!

答案 2 :(得分:35)

虽然接受的答案是非常正确的,但只想指出AllowTransparency有一些垮台。它不允许显示子窗口控件,即WebBrowser,它通常会强制软件渲染,这可能会产生负面的性能影响。

虽然有更好的解决方法。

如果要创建一个没有可调整大小的边框的窗口,并且能够托管WebBrowser控件或指向URL的Frame控件,那么所述控件的内容将显示为空。

我找到了一个解决方法;在Window中,如果你将WindowStyle设置为None,ResizeMode设置为NoResize(忍受我,你仍然可以在完成后重新调整大小)然后确保你有UNCHECKED AllowTransparency你将有一个没有边框的静态大小的窗口并将显示浏览器控件。

现在,您可能仍希望能够正确调整大小?好吧,我们可以通过互操作来实现:

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

答案 3 :(得分: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>

答案 4 :(得分:0)

我很难使用WindowChrome通过@ fernando-aguirre来获得答案。在我的情况下,此方法不起作用,因为我在OnSourceInitialized中覆盖了MainWindow并且没有调用基类方法。

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

这困扰了我很长时间。