【问题标题】:How to create a WPF Window without a border that can be resized?如何创建一个没有可调整大小边框的 WPF 窗口?
【发布时间】:2012-11-22 15:05:20
【问题描述】:

在 WPF 中有没有一种方法可以删除主窗口的边框,但允许调整该窗口的大小(没有夹点)?

我意识到有一种方法可以通过将调整大小模式设置为CanResizeWithGrip 来实现这种情况。但是,我希望能够将调整大小模式设置为CanResize

我尝试设置以下内容:

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

但是,通过设置AllowsTransparency,它会取消在没有夹点的情况下调整大小的功能。有什么想法可以解决这个问题吗?

我还应该注意,无论如何我都不能将AllowsTransparency 设置为true,因为我在我的窗口中使用了一个winformshost 控件,当AllowsTransparency 为true 时不会显示该控件。

【问题讨论】:

  • 我决定改用我的 UI,设置 ResizeMode="CanResize" 并保留边框。

标签: c# wpf window


【解决方案1】:

我知道这是一个老问题,但我只是想为新手提供一个工作示例。

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 准确地表示了窗口在转换到正常状态后将恢复的大小
【解决方案2】:

如果 ResizeBorderThickness 设置为 0,就会发生这种情况。

可以像这样在 XAML 中设置为正值:

<WindowChrome>
    <WindowChrome.ResizeBorderThickness>
        <Thickness>1</Thickness>
    </WindowChrome.ResizeBorderThickness>
</WindowChrome>

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      您可以使用 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,我还没有尝试过,但是这里有一个关于如何解决 WinFormsHost 错误的解决方案mrtncls.blogspot.com/2011/07/… 也是通过 Win API 解决的解决方案neowin.net/forum/topic/…
      • 我尝试了第二种解决方案,没有运气。有时间我会尝试第一个解决方案。感谢您的反馈。
      【解决方案5】:

      最简单,但也许过于简单的是

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

      【讨论】:

      • 我不一定要移动窗口,而只是在拖动边框(我最终只想隐藏)时调整大小。本质上,我想模拟调整窗口大小的一般行为,只是隐藏了边框。
      • 然后你需要捕捉你正在移动的边缘,并根据边缘调整 X、Y、W、H。
      猜你喜欢
      • 2010-10-11
      • 2013-07-12
      • 2011-09-22
      • 2011-02-25
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多