方式一:调用user32.dllAPI
这种方式在网上有很多,这里只是按步骤重新建立一次。读者只需要跟着做就行。
第一步:创建一个WPF项目:WpfResizeWithoutBorder,右键项目文件---->添加----->资源字典,并命名为:WindowsResizeBorderTemplete.xaml。
第二步:在刚刚建立的资源文件(WindowsResizeBorderTemplete.xaml)中复制如下代码:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate x:Key="CustomWindowTemplete" TargetType="Window">
<Border BorderBrush="Transparent" BorderThickness="12" x:Name="outBorder">
<Border.Effect>
<DropShadowEffect BlurRadius="15" Color="#000000" Opacity=".25" Direction="90" ShadowDepth="1"/>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1"/>
<RowDefinition/>
<RowDefinition Height="1"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"/>
<ColumnDefinition/>
<ColumnDefinition Width="1"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" Grid.Column="1" Background="White" >
<AdornerDecorator>
<ContentPresenter></ContentPresenter>
</AdornerDecorator>
</Grid>
<Rectangle Name="ResizeTopLeft" Fill="Red" Grid.Row="0" Grid.Column="0" Opacity=".25"/>
<Rectangle Name="ResizeTop" Fill="Red" Grid.Row="0" Grid.Column="1" Opacity=".25"/>
<Rectangle Name="ResizeTopRight" Fill="Red" Grid.Row="0" Grid.Column="2" Opacity=".25"/>
<Rectangle Name="ResizeLeft" Fill="Red" Grid.Row="1" Grid.Column="0" Opacity=".25"/>
<Rectangle Name="ResizeRight" Fill="Red" Grid.Row="1" Grid.Column="2" Opacity=".25"/>
<Rectangle Name="ResizeBottomLeft" Fill="Red" Grid.Row="2" Grid.Column="0" Opacity=".25"/>
<Rectangle Name="ResizeBottom" Fill="Red" Grid.Row="2" Grid.Column="1" Opacity=".25"/>
<Rectangle Name="ResizeBottomRight" Fill="Red" Grid.Row="2" Grid.Column="2" Opacity=".25"/>
</Grid>
</Border>
</ControlTemplate>
<Style x:Key="CustomWindow" TargetType="Window">
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="Template" Value="{StaticResource CustomWindowTemplete}"></Setter>
</Style>
</ResourceDictionary>
第三步:添加一个类文件:VcreditWindowBehindCode.cs,复制代码如下:
///Editor:Mey Eaphone
///Date:20180929
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WpfResizeWithoutBorder
{
public class VcreditWindowBehindCode : Window
{
public const int WM_SYSCOMMAND = 0x112;
public HwndSource HwndSource;
public Dictionary<ResizeDirection, Cursor> cursors = new Dictionary<ResizeDirection, Cursor>
{
{ResizeDirection.Top, Cursors.SizeNS},
{ResizeDirection.Bottom, Cursors.SizeNS},
{ResizeDirection.Left, Cursors.SizeWE},
{ResizeDirection.Right, Cursors.SizeWE},
{ResizeDirection.TopLeft, Cursors.SizeNWSE},
{ResizeDirection.BottomRight, Cursors.SizeNWSE},
{ResizeDirection.TopRight, Cursors.SizeNESW},
{ResizeDirection.BottomLeft, Cursors.SizeNESW}
};
public enum ResizeDirection
{
Left = 1,
Right = 2,
Top = 3,
TopLeft = 4,
TopRight = 5,
Bottom = 6,
BottomLeft = 7,
BottomRight = 8,
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public VcreditWindowBehindCode()
{
this.SourceInitialized += VcreditWindowBehindCode_SourceInitialized;
this.Loaded += VcreditWindowBehindCode_Loaded;
this.MouseMove += VcreditWindowBehindCode_MouseMove;
}
private void VcreditWindowBehindCode_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton != MouseButtonState.Pressed)
{
FrameworkElement element = e.OriginalSource as FrameworkElement;
if (element != null && !element.Name.Contains("Resize"))
{
this.Cursor = Cursors.Arrow;
}
}
}
private void VcreditWindowBehindCode_SourceInitialized(object sender, EventArgs e)
{
this.HwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
}
private void VcreditWindowBehindCode_Loaded(object sender, RoutedEventArgs e)
{
ControlTemplate customWindowTemplate = App.Current.Resources["CustomWindowTemplete"] as ControlTemplate;
if (customWindowTemplate != null)
{
var TopLeft = customWindowTemplate.FindName("ResizeTopLeft", this) as Rectangle;
TopLeft.MouseMove += ResizePressed;
TopLeft.MouseDown += ResizePressed;
var Top = customWindowTemplate.FindName("ResizeTop", this) as Rectangle;
Top.MouseMove += ResizePressed;
Top.MouseDown += ResizePressed;
var TopRight = customWindowTemplate.FindName("ResizeTopRight", this) as Rectangle;
TopRight.MouseMove += ResizePressed;
TopRight.MouseDown += ResizePressed;
var Left = customWindowTemplate.FindName("ResizeLeft", this) as Rectangle;
Left.MouseMove += ResizePressed;
Left.MouseDown += ResizePressed;
var Right = customWindowTemplate.FindName("ResizeRight", this) as Rectangle;
Right.MouseMove += ResizePressed;
Right.MouseDown += ResizePressed;
var BottomLeft = customWindowTemplate.FindName("ResizeBottomLeft", this) as Rectangle;
BottomLeft.MouseMove += ResizePressed;
BottomLeft.MouseDown += ResizePressed;
var Bottom = customWindowTemplate.FindName("ResizeBottom", this) as Rectangle;
Bottom.MouseMove += ResizePressed;
Bottom.MouseDown += ResizePressed;
var BottomRight = customWindowTemplate.FindName("ResizeBottomRight", this) as Rectangle;
BottomRight.MouseMove += ResizePressed;
BottomRight.MouseDown += ResizePressed;
}
}
public void ResizePressed(object sender, MouseEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
ResizeDirection direction = (ResizeDirection)Enum.Parse(typeof(ResizeDirection), element.Name.Replace("Resize", ""));
this.Cursor = cursors[direction];
if (e.LeftButton == MouseButtonState.Pressed)
{
ResizeWindow(direction);
}
}
public void ResizeWindow(ResizeDirection direction)
{
SendMessage(HwndSource.Handle, WM_SYSCOMMAND, (IntPtr)(61440 + direction), IntPtr.Zero);
}
}
}
第四步:再右键项目文件,添加一个窗体,命名为Window3.xaml。并在文件资源管理器中找到Window3.xaml.cs并点击删除。然后在创建一个类文件Window3.cs。此时项目结构如下所示。
第五步:打开Window3.xaml文件,将复制代码如下:
<local:VcreditWindowBehindCode x:Class="WpfResizeWithoutBorder.Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfResizeWithoutBorder"
Title="MainWindow" Height="350" Width="525"
WindowStyle="None" ResizeMode="CanResizeWithGrip" AllowsTransparency="True"
Style="{StaticResource CustomWindow}"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Canvas Name="nav_Bar" Grid.Row="0" Background="Blue">
<Button Name="btnMax" Content="Max" Canvas.Left="375" Canvas.Top="10" Width="75"/>
</Canvas>
</Grid>
</local:VcreditWindowBehindCode>
第六步:打开Window3.cs文件,然后将代码复制如下
///Editor:Mey Eaphone
///Date:20180929
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfResizeWithoutBorder
{
/// <summary>
///
/// </summary>
public partial class Window3:VcreditWindowBehindCode
{
/// <summary>
///
/// </summary>
public Window3()
{
InitializeComponent();
InitializeRouted();
}
/// <summary>
/// 初始化事件
/// </summary>
private void InitializeRouted()
{
nav_Bar.AddHandler(Canvas.MouseDownEvent, new MouseButtonEventHandler(Window3_MouseMove),true);
btnMax.AddHandler(Button.MouseDoubleClickEvent, new MouseButtonEventHandler(Window3_Maxied), true);
}
/// <summary>
/// 最大普通化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window3_Maxied(object sender, MouseButtonEventArgs e)
{
if (this.WindowState == System.Windows.WindowState.Normal)
{
this.WindowState = System.Windows.WindowState.Maximized;
}
else
{
this.WindowState = System.Windows.WindowState.Normal;
}
}
/// <summary>
/// 窗体拖动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window3_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
this.DragMove();
}
}
}
第七步:打开App.xaml文件,将复制代码,修改为:
<Application x:Class="WpfResizeWithoutBorder.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window3.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowsResizeBorderTemplete.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
最后F5查看效果。
方式二:直接使用WindowChrome(.Net4.5.1以上)
第一种方式非常复杂,在.net4.5.1之后,迎来了革新的东西——WindowChrome,使用方法很简单。
第一步:新建窗体Window1.xaml,打开文件,并复制代码如下:
<Window x:Class="WpfResizeWithoutBorder.Window1"
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:WpfResizeWithoutBorder"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Window.Style>
<Style TargetType="Window">
<Setter Property="Background" Value="Transparent" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="ResizeMode" Value="CanResize" />
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="80" ResizeBorderThickness="20" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Border Padding="10">
<Border Background="White"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="4"
SnapsToDevicePixels="True">
<!--阴影效果-->
<!--<Border.Effect>
<DropShadowEffect BlurRadius="10"
Direction="0"
ShadowDepth="0" />
</Border.Effect>-->
<ContentPresenter />
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>
</Window>
第二步:修改App.xaml文件的启动链接,复制代码如下:
<Application x:Class="WpfResizeWithoutBorder.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowsResizeBorderTemplete.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
最后F5,出现的效果是不是你想要的,是不是很简单。
总结:
1.方法一比较复杂,但是我们很清楚从无到有的整个过程,值得我们深入学习研究。
2.方法二简单粗暴,使用.net新属性,分分钟搞定,实用性高。