如何创建一个没有边框且可调整大小的WPF窗口?

9

在WPF中,是否有一种方法可以去除主窗口的边框,同时允许该窗口调整大小(无握柄)?

我意识到可以通过将调整模式设置为CanResizeWithGrip来实现此场景。但是,我想能够使用调整模式设置为CanResize来实现。

我尝试了以下设置:

ResizeMode="CanResize" 
WindowStyle="None"
AllowsTransparency="True"

然而,通过设置AllowsTransparency,可以去除无法使用把手调整大小的功能。你有什么想法可以解决这个问题吗?
我还应该说明的是,我不能将AllowsTransparency设置为true,因为我在窗口中使用了winformshost控件,当AllowsTransparency为true时,它不会显示。

我决定重新设计我的用户界面,只需设置ResizeMode="CanResize"并保留边框即可。 - jsirr13
5个回答

5

我知道这是一个老问题,但我想为新手提供一个可用的示例。

Xaml 窗口:

<Window x:Class="CustomWindowDemo.DemoCustomWindow"
        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:CustomWindowDemo"
        mc:Ignorable="d"
        Title="DemoCustomWindow" Height="300" Width="300" Background="{x:Null}" AllowsTransparency="True" WindowStyle="None">
    <Window.Resources>
        <Style x:Key="BorderThumb" TargetType="Thumb">
            <Setter Property="SnapsToDevicePixels" Value="true" />
            <Setter Property="OverridesDefaultStyle" Value="true" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Thumb">
                        <Rectangle MinWidth="4" MinHeight="4" StrokeThickness="0">
                            <Rectangle.Fill>
                                <SolidColorBrush Color="{DynamicResource {x:Static SystemColors.HighlightColorKey}}" Opacity="0.05"/>
                            </Rectangle.Fill>
                        </Rectangle>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Border BorderBrush="#55FFFFFF" BorderThickness="1" CornerRadius="5">
        <Grid>
            <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
            <Border MouseMove="Header_MouseMove" DockPanel.Dock="Top" Height="32"  Grid.Row="1" Grid.Column="1">
                    <Border.Background>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,3">
                            <GradientStop Color="#3BB2EA" Offset="0" />
                            <GradientStop Color="#EFF7FA" Offset="0.3" />
                        </LinearGradientBrush>
                    </Border.Background>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0" Text="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
                        <Button x:Name="btn_Minimize" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Click="btn_Minimize_Click" Grid.Column="1">
                            <Image Source="Resources/Ahmadhania-Spherical-Minimize.ico"/>
                        </Button>
                        <Button x:Name="btn_Maximize" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Grid.Column="2" Click="btn_Maximize_Click">
                            <Image Source="Resources/1412181205_61002.ico"/>
                        </Button>
                        <Button x:Name="btn_Close" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Grid.Column="3" Click="btn_Close_Click">
                            <Image Source="Resources/Ahmadhania-Spherical-Close(1).ico"/>
                        </Button>
                    </Grid>
                </Border>
            <Thumb x:Name="ThumbBottom" DragDelta="ThumbBottom_DragDelta" HorizontalAlignment="Stretch" Cursor="SizeNS" Grid.Column="0" Background="{x:Null}"  Margin="3,0" Grid.ColumnSpan="3" Grid.Row="3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
            <Thumb x:Name="ThumbTop" DragDelta="ThumbTop_DragDelta" HorizontalAlignment="Stretch" Cursor="SizeNS" Grid.Column="0" Background="{x:Null}"  Margin="3,0" Grid.ColumnSpan="3" Height="4" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
            <Thumb x:Name="ThumbBottomRightCorner" DragDelta="ThumbBottomRightCorner_DragDelta" HorizontalAlignment="Right" Cursor="SizeNWSE" Grid.Row="3" Grid.Column="3" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
            <Thumb x:Name="ThumbTopRightCorner" DragDelta="ThumbTopRightCorner_DragDelta" HorizontalAlignment="Right" Cursor="SizeNESW" Grid.Row="0" Grid.Column="2" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
            <Thumb x:Name="ThumbTopLeftCorner" DragDelta="ThumbTopLeftCorner_DragDelta" HorizontalAlignment="Left" Cursor="SizeNWSE" Grid.Row="0" Grid.Column="0" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}" />
            <Thumb x:Name="ThumbBottomLeftCorner" DragDelta="ThumbBottomLeftCorner_DragDelta" HorizontalAlignment="Left" Cursor="SizeNESW" Grid.Row="3" Grid.Column="0" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}" />
            <Thumb x:Name="ThumbRight" DragDelta="ThumbRight_DragDelta" Cursor="SizeWE" Grid.Column="2" Grid.RowSpan="4" Background="{x:Null}"  Margin="0,3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
            <Thumb x:Name="ThumbLeft" DragDelta="ThumbLeft_DragDelta" Cursor="SizeWE" Grid.Column="0" Grid.RowSpan="4" HorizontalContentAlignment="Right" Background="{x:Null}" Margin="0,3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
            <Grid x:Name="Grid_Content" Background="#EFF7FA" Grid.Row="2" Grid.Column="1">

            </Grid>
        </Grid>
    </Border>
</Window>

C#代码后台:

using System.Windows.Interop;
using winforms = System.Windows.Forms;

namespace CustomWindowDemo
{
    /// <summary>
    /// Interaction logic for DemoCustomWindow.xaml
    /// </summary>
    public partial class DemoCustomWindow : Window
    {
        bool Maximized = false;
        int NormalWidth = 0;
        int NormalHeight = 0;
        int NormalX = 0;
        int NormalY = 0;

        public DemoCustomWindow()
        {
            InitializeComponent();
        }

        #region Header & Resize
        void Header_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
                this.DragMove();
        }

        void ThumbBottomRightCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (this.Width + e.HorizontalChange > 10)
                this.Width += e.HorizontalChange;
            if (this.Height + e.VerticalChange > 10)
                this.Height += e.VerticalChange;
        }
        void ThumbTopRightCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (this.Width + e.HorizontalChange > 10)
                this.Width += e.HorizontalChange;
            if (this.Top + e.VerticalChange > 10)
            {
                this.Top += e.VerticalChange;
                this.Height -= e.VerticalChange;
            }
        }
        void ThumbTopLeftCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (this.Left + e.HorizontalChange > 10)
            {
                this.Left += e.HorizontalChange;
                this.Width -= e.HorizontalChange;
            }
            if (this.Top + e.VerticalChange > 10)
            {
                this.Top += e.VerticalChange;
                this.Height -= e.VerticalChange;
            }
        }
        void ThumbBottomLeftCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (this.Left + e.HorizontalChange > 10)
            {
                this.Left += e.HorizontalChange;
                this.Width -= e.HorizontalChange;
            }
            if (this.Height + e.VerticalChange > 10)
                this.Height += e.VerticalChange;
        }
        void ThumbRight_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (this.Width + e.HorizontalChange > 10)
                this.Width += e.HorizontalChange;
        }
        void ThumbLeft_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (this.Left + e.HorizontalChange > 10)
            {
                this.Left += e.HorizontalChange;
                this.Width -= e.HorizontalChange;
            }
        }
        void ThumbBottom_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (this.Height + e.VerticalChange > 10)
                this.Height += e.VerticalChange;
        }
        void ThumbTop_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            if (this.Top + e.VerticalChange > 10)
            {
                this.Top += e.VerticalChange;
                this.Height -= e.VerticalChange;
            }
        }

        void btn_Minimize_Click(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }
        void btn_Maximize_Click(object sender, RoutedEventArgs e)
        {
            if (Maximized == true)
            {
                this.Width = NormalWidth;
                this.Height = NormalHeight;
                this.Left = NormalX;
                this.Top = NormalY;
                Maximized = false;
                Thumbs();
            }
            else
            {
                NormalX = (int)this.Left;
                NormalY = (int)this.Top;
                NormalHeight = (int)this.Height;
                NormalWidth = (int)this.Width;
                this.Left = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Left;
                this.Top = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Top;
                this.Width = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Width;
                this.Height = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Height;
                Maximized = true;
                Thumbs();
            }
        }
        void btn_Close_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
        void Thumbs()
        {
            if (Maximized == true)
            {
                ThumbBottom.Visibility = Visibility.Collapsed;
                ThumbLeft.Visibility = Visibility.Collapsed;
                ThumbTop.Visibility = Visibility.Collapsed;
                ThumbRight.Visibility = Visibility.Collapsed;
                ThumbTopLeftCorner.Visibility = Visibility.Collapsed;
                ThumbTopRightCorner.Visibility = Visibility.Collapsed;
                ThumbBottomLeftCorner.Visibility = Visibility.Collapsed;
                ThumbBottomRightCorner.Visibility = Visibility.Collapsed;
            }
            else
            {
                ThumbBottom.Visibility = Visibility.Visible;
                ThumbLeft.Visibility = Visibility.Visible;
                ThumbTop.Visibility = Visibility.Visible;
                ThumbRight.Visibility = Visibility.Visible;
                ThumbTopLeftCorner.Visibility = Visibility.Visible;
                ThumbTopRightCorner.Visibility = Visibility.Visible;
                ThumbBottomLeftCorner.Visibility = Visibility.Visible;
                ThumbBottomRightCorner.Visibility = Visibility.Visible;
            }
        }
        #endregion
    }
}

据我所记,有一个属性 Window.RestoreBounds,它代表窗口在从正常状态转换回来后恢复的确切大小。 - Demarsch

1
如果将 ResizeBorderThickness 设置为 0,可能会发生这种情况。
可以在 XAML 中设置为正值,如下所示:
<WindowChrome>
    <WindowChrome.ResizeBorderThickness>
        <Thickness>1</Thickness>
    </WindowChrome.ResizeBorderThickness>
</WindowChrome>

0

您可以使用WPF可自定义窗口库,该库在此处提供:http://wpfwindow.codeplex.com/

然后,在使用库的窗口类型时,您可以设置与上面列出的相同属性

<CustomWindow:EssentialWindow x:Class="CustomWindowDemo.DemoEssentialWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:CustomWindow="clr-namespace:CustomWindow;assembly=CustomWindow"
    AllowsTransparency="True" ResizeMode="CanResize" WindowStyle="None" Title="EssentialWindow"
    Height="300" Width="250">

在他们的网站上,它说:只有当AllowsTransparency设置为“True”时,才能完成WPF窗口的完全自定义。不幸的是,由于WinFormsHost的错误,当AllowsTransparency设置为true时,控件无法显示。也许如果我能解决这个问题,你的回答将是一个接近理想的解决方案。 - jsirr13
@jsirr13,虽然我没有尝试过,但这是一个解决WinFormsHost bug的方法:http://mrtncls.blogspot.com/2011/07/windowsformshost-on-transparent-wpf.html 还有一种通过Win API解决的方案:http://www.neowin.net/forum/topic/646970-c%23-wpf-window-with-transparency-makes-windowsformshost-disappear/ - d.moncada
我尝试了第二个解决方案,但没有成功。等我有时间了,我会尝试第一个解决方案。感谢您的反馈。 - jsirr13

0
用户需要与之交互以调整窗口大小。如果您不喜欢默认的边框或手柄,则需要添加一些其他控件,具有单击和拖动行为来调整窗口大小。也许在窗口的每个边缘上加一条线?

-5

最简单的,但可能太简单了

this.MouseLeftButtonDown += delegate { this.DragMove(); };

我并不一定想移动窗口,而只是在拖动边框(最终我只想隐藏它)时调整大小。本质上,我想模拟调整窗口大小的一般行为,只是将边框隐藏。 - jsirr13
然后,您需要捕获正在移动的边缘,并根据该边缘调整X、Y、W、H。 - kenny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接