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

.net 如何创建没有边框的WPF窗口,该边框只能通过夹点调整大小?,.net,wpf,window,controltemplate,resizegrip,.net,Wpf,Window,Controltemplate,Resizegrip,如果在WPF窗口上设置ResizeMode=“CanResizeWithGrip”,则右下角将显示一个调整大小夹点,如下所示: 如果同时设置WindowStyle=“None”,则标题栏将消失,但灰色斜边将保留,直到设置ResizeMode=“NoResize”。不幸的是,设置了这些属性组合后,“调整大小”夹点也会消失 我已通过自定义样式覆盖了窗口的控制模板。我想自己指定窗口的边框,我不需要用户能够从四面调整窗口的大小,但我需要一个调整大小的夹点 有人能详细说明满足所有这些标准的简单方法吗 除

如果在WPF
窗口上设置
ResizeMode=“CanResizeWithGrip”
,则右下角将显示一个调整大小夹点,如下所示:

如果同时设置
WindowStyle=“None”
,则标题栏将消失,但灰色斜边将保留,直到设置
ResizeMode=“NoResize”
。不幸的是,设置了这些属性组合后,“调整大小”夹点也会消失

我已通过自定义
样式
覆盖了
窗口的
控制模板
。我想自己指定窗口的边框,我不需要用户能够从四面调整窗口的大小,但我需要一个调整大小的夹点

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

  • 除了我在
    控制模板
    中指定的边框外,在
    窗口上不要有边框
  • 在右下角有一个可用的调整大小夹点
  • 没有标题栏

  • 如果在
    窗口
    上设置
    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>
    
    
    
    结果如下:

    此处示例:

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

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

    不过还有更好的办法

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

    我找到了一个解决办法;在窗口中,如果您将WindowsStyle设置为None,将ResizeMode调整为NoResize(恕我直言,完成后您仍然可以调整大小),然后确保取消选中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等控件的兼容性。我试图创建一个带有
    WindowStyle=“None”
    的无边框窗口,但当我测试它时,它的顶部似乎出现了一个白色条,经过一些研究,它似乎是一个“调整边框大小”的窗口,这是一张图片(我用黄色表示):

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


    谢谢大家!

    我在@fernando aguirre使用
    WindowChrome
    工作时很难得到答案。在我的例子中,它不起作用,因为我在
    main窗口中重写
    OnSourceInitialized
    ,而没有调用基类方法

    protected override void OnSourceInitialized(EventArgs e)
    {
        ViewModel.Initialize(this);
        base.OnSourceInitialized(e); // <== Need to call this!
    }
    
    sourceInitialized上的受保护覆盖无效(EventArgs e)
    {
    初始化(这个);
    
    基础。资源初始化(e);//纯属侥幸,我知道这一点-我今天下午玩的是同一个控件集。:)哇,我没想到会这样,但它完全可以在5分钟内制作您自己的post-it-notes,谢谢:)AllowTransparency有几个缺点,不过Windows不能再承载子窗口控件,例如WebBrowser,通常会强制软件渲染铃声,已报告内存泄漏。请参阅下面我的解决方法。您只需要WindowStyle=“无”要去除边框,AllowTransparency只需要它,但不会影响边框。@Grault这会去除窗口标题,但表单周围仍然有一个实心边框。AllowTransparency会去除边框。您应该简要说明代码的工作原理。请注意,AllowTransparency会创建内存泄漏。因此请避免使用它。请参考@DipeshBhatt,我在您提供的链接中找不到任何关于该声明的解释。也许您是想发布链接,尽管我已将窗口样式设置为无,但我在顶部面对灰色边缘。ResizeMode=“NoResize”解决了我的问题。如果我们想从各个方面调整大小,而不仅仅是从右下角调整大小,但仍然不想看到边框,我们应该怎么做?以下是其他wParam值,只需根据需要使用这些
    private enum ResizeDirection将新事件分配给新的UI对象即可{左=61441,右=61442,上=61443,上左=61444,上右=61445,下=61446,下左=61447,下右=61448,}
    这对我来说非常有用,但有一个例外,就是一旦你有了NoResize,你就不能用dr
    <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>
    
    protected override void OnSourceInitialized(EventArgs e)
    {
        ViewModel.Initialize(this);
        base.OnSourceInitialized(e); // <== Need to call this!
    }