在windows的开发中,常常有自定义窗口外观的需要。通常都是设置WindowStyle="None",然后在客户区模拟一个标题栏。然而在模拟标题栏的时候会发现一个问题:你已经把自定义的标题栏放在界面的最上方了,可是上边总还会有有一部分空白(如果给标题栏设置个深色背景,会很容易发现)。这是什么原因呢?因为窗口的ResizeMode并不为None,它在客户区的周围仍保留有一部分空间,使得可以通过鼠标拖拽修改窗口大小。这对于我来说是无法接受的,于是设置ResizeMode="None",那这个时候就需要自己来完成鼠标拖拽修改窗口大小的功能。
下面是XAML文件及其界面效果:
<Window x:Class="WindowStyleNone.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" AllowsTransparency="True"
WindowStyle="None" Background="Transparent">
<Border Width="Auto" Height="Auto" Name="windowFrame" BorderBrush="#395984"
BorderThickness="1" CornerRadius="0,20,30,40"
MouseMove="windowFrame_MouseMove"
MouseLeftButtonUp="windowFrame_MouseLeftButtonUp"
MouseLeftButtonDown="windowFrame_MouseLeftButtonDown"
>
<Border.Background>
<SolidColorBrush Color="AliceBlue"></SolidColorBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="Title Bar" Name="TitleBar" Margin="2" Padding="5"></TextBlock>
<Grid Grid.Row="1" Background="#B5CBEF">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center"
Foreground="White" FontSize="20" Text="Content Goes Here"></TextBlock>
</Grid>
<TextBlock Name="foot" Grid.Row="2" Text="Footer" Margin="1,10,1,1" Padding="5" HorizontalAlignment="Center"></TextBlock>
</Grid>
</Border>
</Window>
后台程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WindowStyleNone
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private Point CursorOriginPoint;
private int Gap=4;
private bool IsMouseDown = false;
public MainWindow()
{
InitializeComponent();
}
private void windowFrame_MouseMove(object sender, MouseEventArgs e)
{
Point pt = e.GetPosition(this);
Point spt = this.PointToScreen(pt);
if (!IsMouseDown)
{
this.Cursor = Cursors.Arrow;
if (pt.X > this.Width - this.Gap) this.Cursor = Cursors.SizeWE;
if (pt.Y > this.Height - this.Gap) this.Cursor = Cursors.SizeNS;
}
else
{
if (this.Cursor.Equals(Cursors.SizeWE)) this.Width += Point.Subtract(spt, CursorOriginPoint).X;
if (this.Cursor.Equals(Cursors.SizeNS)) this.Height += Point.Subtract(spt, CursorOriginPoint).Y;
}
CursorOriginPoint = spt;
}
private void windowFrame_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.Source.Equals(this.TitleBar))
{
this.DragMove();
}
else
{
Border border = sender as Border;
border.CaptureMouse();
this.IsMouseDown = true;
this.CursorOriginPoint = this.PointToScreen(e.GetPosition(this));
this.foot.Text = "Down";
}
}
private void windowFrame_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Border border = sender as Border;
if(border.IsMouseCaptured) border.ReleaseMouseCapture();
this.IsMouseDown = false;
this.Cursor = Cursors.Arrow;
this.foot.Text = "Up";
}
}
}