WPF自带的窗体边框和标题栏只包含基础的功能,无法满足项目的视觉效果,经常会遇到需要去掉框架自带标题栏的情况。
现总结如下:
首先,通过WindowChrome
自定义窗口样式:
<WindowChrome.WindowChrome>
<WindowChrome CornerRadius="10" GlassFrameThickness="10" ResizeBorderThickness="4" CaptionHeight="0" />
</WindowChrome.WindowChrome>
其次,使用一个StackPanel
来模拟标题栏的功能:
最后,通过代码定义行为:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Window_StateChanged(null, null);
}
private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
if (this.ResizeMode != ResizeMode.CanResize && this.ResizeMode != ResizeMode.CanResizeWithGrip)
{
return;
}
if (this.WindowState == WindowState.Maximized)
{
this.WindowState = WindowState.Normal;
}
else
{
this.WindowState = WindowState.Maximized;
}
}
else
{
this.DragMove();
}
}
private void StackPanel_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var mousePostion = e.MouseDevice.GetPosition(this);
var point = PointToScreen(mousePostion);
this.Left = point.X - (this.RestoreBounds.Width * 0.5);
this.Top = point.Y;
this.WindowState = WindowState.Normal;
this.DragMove();
}
}
private void Window_StateChanged(object sender, EventArgs e)
{
if (this.WindowState == WindowState.Maximized)
{
this.BorderThickness = new Thickness(8);
}
else
{
this.BorderThickness = new Thickness(0);
}
}
}
(注意:当窗体最大化时,内容与屏幕会有一个负8的margin,所以在Window_StateChanged
里判断当Maximized
时手动补偿正8的margin。)
效果:
无边框窗体样式