经过几个小时的努力终于做出WPF自定义窗口,学习了这么久的编程总算有一些东西能和大家分享一下,希望能对和我一样独自摸索编程这条路的码友一下启发和帮助。
由于不是没专业学过美工可能一下图绘制不是很好,自定义了三个控件(关闭、最大化、最小化),也就是一共四个xaml文件
一、做出效果图表框有透明效果,可用鼠标拖拽窗口大小。
二、xaml代码
1、关闭按钮的xaml
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication2" x:Class="ExitButton"
mc:Ignorable="d" d:DesignWidth="30" Height="30">
<Grid x:Name="GridBasic">
<Grid.Resources>
<Style x:Key="PathStyle" TargetType="{x:Type Path}">
<Setter Property="Stroke" Value="Black"/>
<Setter Property="StrokeThickness" Value="2"/>
</Style>
</Grid.Resources>
<Path Margin="5,7" Stretch="Fill" Style="{StaticResource PathStyle}" Data="M60,0 Q30,30 0,60"/>
<Path Margin="5,7" Stretch="Fill" Style="{StaticResource PathStyle}" Data="M0,0 Q30,30 60,60"/>
</Grid>
</UserControl>
2、最大化按钮的xaml
<UserControl x:Class="MaxButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" d:DesignWidth="30" Height="30">
<Grid>
<Rectangle Margin="5,10,0,0" Stroke="Black" Height="8" VerticalAlignment="Top" HorizontalAlignment="Left" Width="12" StrokeThickness="2"/>
<Rectangle Margin="10,6,0,0" Stroke="Black" Height="9" VerticalAlignment="Top" HorizontalAlignment="Left" Width="13" StrokeThickness="2"/>
</Grid>
</UserControl>
3、最小化按钮的xaml
<UserControl x:Class="MinButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" d:DesignWidth="30" Height="30">
<Grid>
<Rectangle Height="3" Margin="7,14,0,0" Stroke="Black" StrokeThickness="2" VerticalAlignment="Top" HorizontalAlignment="Left" Width="16"/>
</Grid>
</UserControl>
4、主窗体的xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
x:Class="MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterScreen" MinHeight="480" MinWidth="640">
<Window.Resources>
<Style x:Key="ToolBarSunStyle" TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="#FFD9E4F1"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFFDECD2" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="#FFE2A040" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ToolBarStyle" TargetType="{x:Type ToolBar}">
<Setter Property="Background" Value="#FFD9E4F1"/>
</Style>
</Window.Resources>
<Window.Background>
<SolidColorBrush Color="White" Opacity="0"/>
</Window.Background>
<Grid>
<Grid.Resources>
<Style x:Key="ExitButton" TargetType="UserControl">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFFDECD2" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="#FFE2A040" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="TitleStyle" TargetType="Grid">
<Setter Property="Background" Value="#FFD9E4F1"/>
</Style>
<Style x:Key="MenuStyle" TargetType="Menu">
<Setter Property="Background" Value="#FFD9E4F1"/>
</Style>
<Style x:Key="MenuItemFatherStyle" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFFDECD2" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="#FFE2A040" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="MenuItemStyle" TargetType="MenuItem">
<Setter Property="Background" Value="#FFD9E4F1"/>
</Style>
<Style x:Key="ToolBarPanelStyle" TargetType="ToolBarPanel">
<Setter Property="Background" Value="#FFD9E4F1"/>
</Style>
<Style x:Key="ToolBarTrayStyle" TargetType="ToolBarTray">
<Setter Property="Background" Value="#FFD9E4F1"/>
</Style>
<Style x:Key="ToolBarStyle" TargetType="ToolBar">
<Setter Property="Background" Value="#FFD9E4F1"/>
</Style>
<Style x:Key="ToolBarSunStyle" TargetType="TabItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFFDECD2" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="#FFE2A040" />
</Trigger>
</Style.Triggers>
<Setter Property="Background" Value="#FFD9E4F1"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="78*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="8"/>
<RowDefinition Height="58*"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border CornerRadius="10,10,10,10" BorderThickness="8" Background="#FFFFFFFF" Grid.RowSpan="3" Grid.ColumnSpan="3">
<Border.BorderBrush>
<SolidColorBrush Color="#CC8FBFE8" Opacity="0.8"/>
</Border.BorderBrush>
<Border CornerRadius="8,8,8,8" Background="#99FFFFFF">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="405*"/>
</Grid.RowDefinitions>
<Grid Style="{StaticResource TitleStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="525*"/>
<ColumnDefinition Width="98"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,518,0"/>
<Label x:Name="WindowTitleLabel" Content="WpfApplication" Grid.Column="1"/>
<local:ExitButton x:Name="ExitButton" Grid.Column="2" HorizontalAlignment="Left" Margin="62,0,0,0" VerticalAlignment="Top" Width="29" Height="25" Style="{StaticResource ExitButton}"/>
<local:MaxButton x:Name="MaxButton" Grid.Column="2" HorizontalAlignment="Left" Height="25" Margin="31,0,0,0" VerticalAlignment="Top" Width="31" Style="{StaticResource ExitButton}"/>
<local:MinButton x:Name="MinButton" Grid.Column="2" HorizontalAlignment="Left" Height="25" VerticalAlignment="Top" Width="31" Style="{StaticResource ExitButton}" />
</Grid>
<Grid Grid.Row="1">
<Menu Style="{StaticResource MenuStyle}">
<MenuItem Header="文件(F)" Style="{StaticResource MenuItemFatherStyle}">
<MenuItem Header="新建项目" />
<MenuItem Header="打开项目" />
</MenuItem>
</Menu>
</Grid>
<Grid Grid.Row="2">
<ToolBarPanel Style="{StaticResource ToolBarPanelStyle}">
<ToolBarTray Style="{StaticResource ToolBarTrayStyle}">
<ToolBar Style="{StaticResource ToolBarStyle}" Height="18">
<TabItem Style="{StaticResource ToolBarSunStyle}"/>
</ToolBar>
<ToolBar Style="{StaticResource ToolBarStyle}" Height="18">
<TabItem Style="{StaticResource ToolBarSunStyle}"/>
</ToolBar>
</ToolBarTray>
</ToolBarPanel>
</Grid>
</Grid>
</Border>
</Border>
</Grid>
</Window>
三、主窗体VB代码
Imports System.Windows.Interop
Class MainWindow
'枚举消息
Public Enum HitTest As Integer
HTERROR = -2
HTTRANSPARENT = -1
HTNOWHERE = 0
HTCLIENT = 1
HTCAPTION = 2
HTSYSMENU = 3
HTGROWBOX = 4
HTSIZE = HTGROWBOX
HTMENU = 5
HTHSCROLL = 6
HTVSCROLL = 7
HTMINBUTTON = 8
HTMAXBUTTON = 9
HTLEFT = 10
HTRIGHT = 11
HTTOP = 12
HTTOPLEFT = 13
HTTOPRIGHT = 14
HTBOTTOM = 15
HTBOTTOMLEFT = 16
HTBOTTOMRIGHT = 17
HTBORDER = 18
HTREDUCE = HTMINBUTTON
HTZOOM = HTMAXBUTTON
HTSIZEFIRST = HTLEFT
HTSIZELAST = HTBOTTOMRIGHT
HTOBJECT = 19
HTCLOSE = 20
HTHELP = 21
End Enum
'消息处理函数
Protected Overrides Sub OnSourceInitialized(e As EventArgs)
MyBase.OnSourceInitialized(e)
Dim hwndSource As HwndSource = TryCast(PresentationSource.FromVisual(Me), HwndSource)
If hwndSource IsNot Nothing Then
hwndSource.AddHook(New HwndSourceHook(AddressOf Me.WndProc))
End If
End Sub
#Region "标题栏控制"
Dim MaxState As Boolean = False '窗口最大化状态
'标题栏拖地窗口
Private Sub WindowTitleLabel_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles WindowTitleLabel.MouseLeftButtonDown
Me.DragMove()
End Sub
'关闭程序
Private Sub ExitButton_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles ExitButton.MouseLeftButtonDown
Me.Close()
End Sub
'最大化切换
Private Sub MaxButton_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles MaxButton.MouseLeftButtonDown
If MaxState = False Then
Me.WindowState = Windows.WindowState.Maximized
MaxState = True
Else
Me.WindowState = Windows.WindowState.Normal
MaxState = False
End If
End Sub
'标题栏双击切换最大化
Private Sub WindowTitleLabel_MouseDoubleClick(sender As Object, e As MouseButtonEventArgs) Handles WindowTitleLabel.MouseDoubleClick
If MaxState = False Then
Me.WindowState = Windows.WindowState.Maximized
MaxState = True
Else
Me.WindowState = Windows.WindowState.Normal
MaxState = False
End If
End Sub
'最小化窗口
Private Sub MinButton_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles MinButton.MouseLeftButtonDown
Me.WindowState = Windows.WindowState.Minimized
End Sub
'加载窗体
Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Me.MaxWidth = SystemParameters.WorkArea.Width + 16 '设置窗口最大化的宽度
Me.MaxHeight = SystemParameters.WorkArea.Height + 17 '设置窗口最大化的高度
End Sub
#Region "鼠标控制窗口尺寸"
Private Const WM_NCHITTEST As Integer = &H84
Private mousePoint As Point = New Point() '鼠标坐标
Private Const ResizeBorderAGWidth As Integer = 12 '转角宽度
Private Const ResizeBorderThickness As Integer = 4 '边框宽度
Protected Overridable Function WndProc(hwnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr, ByRef handled As Boolean) As IntPtr
Select Case msg
Case WM_NCHITTEST
Me.mousePoint.X = (lParam.ToInt32() And &HFFFF)
Me.mousePoint.Y = (lParam.ToInt32() >> 16)
' 窗口左上角
If Me.mousePoint.Y - Me.Top <= MainWindow.ResizeBorderAGWidth AndAlso Me.mousePoint.X - Me.Left <= MainWindow.ResizeBorderAGWidth Then
handled = True
Return New IntPtr(CInt(HitTest.HTTOPLEFT))
' 窗口左下角
ElseIf Me.ActualHeight + Me.Top - Me.mousePoint.Y <= MainWindow.ResizeBorderAGWidth AndAlso Me.mousePoint.X - Me.Left <= MainWindow.ResizeBorderAGWidth Then
handled = True
Return New IntPtr(CInt(HitTest.HTBOTTOMLEFT))
' 窗口右上角
ElseIf Me.mousePoint.Y - Me.Top <= MainWindow.ResizeBorderAGWidth AndAlso Me.ActualWidth + Me.Left - Me.mousePoint.X <= MainWindow.ResizeBorderAGWidth Then
handled = True
Return New IntPtr(CInt(HitTest.HTTOPRIGHT))
' 窗口右下角
ElseIf Me.ActualWidth + Me.Left - Me.mousePoint.X <= MainWindow.ResizeBorderAGWidth AndAlso Me.ActualHeight + Me.Top - Me.mousePoint.Y <= MainWindow.ResizeBorderAGWidth Then
handled = True
Return New IntPtr(CInt(HitTest.HTBOTTOMRIGHT))
' 窗口左侧
ElseIf Me.mousePoint.X - Me.Left <= MainWindow.ResizeBorderThickness Then
handled = True
Return New IntPtr(CInt(HitTest.HTLEFT))
' 窗口右侧
ElseIf Me.ActualWidth + Me.Left - Me.mousePoint.X <= MainWindow.ResizeBorderThickness Then
handled = True
Return New IntPtr(CInt(HitTest.HTRIGHT))
' 窗口上方
ElseIf Me.mousePoint.Y - Me.Top <= MainWindow.ResizeBorderThickness Then
handled = True
Return New IntPtr(CInt(HitTest.HTTOP))
' 窗口下方
ElseIf Me.ActualHeight + Me.Top - Me.mousePoint.Y <= MainWindow.ResizeBorderThickness Then
handled = True
Return New IntPtr(CInt(HitTest.HTBOTTOM))
Else
' 窗口移动
'handled = true;
'return new IntPtr((int)HitTest.HTCAPTION);
Return IntPtr.Zero
End If
End Select
Return IntPtr.Zero
End Function
#End Region
#End Region
End Class