WPF 自定义窗口

时间:2022-09-08 00:17:35

在WPF中,经常需要对窗口进行设置,下面讲讲常用的几个设置。

1、无边框窗口

WindowStyle="None" 窗口样式无

AllowsTransparency="True" Background="Transparent" 背景透明

可以用Border的CornerRadius设置窗口四周圆角

设置窗口阴影--值得一提的是,如果直接用Window.Effect,效果会影响CornerRadius设置的圆角效果。

<Window.Effect>
<DropShadowEffect BlurRadius="30" Color="Gray" ShadowDepth="0" RenderingBias="Quality" ></DropShadowEffect>
</Window.Effect>

举例:

WPF 自定义窗口WPF 自定义窗口
<Window x:Class="WpfApplication4.MainWindow"
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"
mc:Ignorable
="d"
Title
="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen"
AllowsTransparency
="True" WindowStyle="None" Background="Transparent">
<Grid>
<Border CornerRadius="5" Background="Red"></Border>
</Grid>
</Window>
View Code

2、窗口按钮

当我们设置无边窗口时,也即是需要重新设置一套窗口的操作按钮。

WPF 自定义窗口

按钮,可以用修改Button的Background或者修改Template,往其中设置图标或者直接用Path、Border、Rectangle等基础元素绘制。

1) 方法1.下面是自定义的按钮Style,往其中传入图标路径即可

WPF 自定义窗口WPF 自定义窗口
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Rectangle x:Name="T_Rectangle" Height="15" Width="15">
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding ImagesSource}"></ImageBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"></ContentPresenter>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="T_Rectangle" Property="Height" Value="18"></Setter>
<Setter TargetName="T_Rectangle" Property="Width" Value="18"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="T_Rectangle" Property="Height" Value="20"></Setter>
<Setter TargetName="T_Rectangle" Property="Width" Value="20"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
View Code

2)方法2.直接用基础元素绘制

WPF 自定义窗口WPF 自定义窗口
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Button x:Name="BtnMinimize" ToolTip="Minimize" Style="{StaticResource TitleBtnStyle}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border x:Name="T_Grid" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Path x:Name="T_Path" Data="M0,0 L8,0" Stroke="Black" StrokeThickness="1"></Path>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger SourceName="T_Grid" Property="IsMouseOver" Value="True">
<Setter TargetName="T_Grid" Property="Background" Value="LightGray"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="T_Grid" Property="Background" Value="#FFC1C1C1"></Setter>
<Setter TargetName="T_Path" Property="Margin" Value="0,4,0,0"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<Button x:Name="BtnMaximize" ToolTip="Maximize" Style="{StaticResource TitleBtnStyle}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border x:Name="T_Grid" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
<Rectangle x:Name="T_Rect" Stroke="Black" StrokeThickness="0.5" Height="8" Margin="5,0" Width="8"></Rectangle>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="T_Grid" Property="Background" Value="LightGray"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="T_Grid" Property="Background" Value="#FFC1C1C1"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<Button x:Name="BtnRestore" ToolTip="Restore" Style="{StaticResource TitleBtnStyle}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border x:Name="T_Grid" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
<Grid >
<Rectangle Stroke="Black" StrokeThickness="0.5" Height="7" Width="7" Margin="2,0,0,2"></Rectangle>
<Rectangle Stroke="Black" StrokeThickness="0.5" Height="7" Width="7" Fill="White" Margin="0,2,2,0"></Rectangle>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="T_Grid" Property="Background" Value="LightGray"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="T_Grid" Property="Background" Value="#FFC1C1C1"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<Button x:Name="BtnClose" ToolTip="Close" Style="{StaticResource TitleBtnStyle}" Click="BtnClose_OnClick">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border x:Name="T_Grid" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Path Data="M0,0 L8,8" Stroke="Black" StrokeThickness="1"></Path>
<Path Data="M8,0 L0,8" Stroke="Black" StrokeThickness="1"></Path>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="T_Grid" Property="Background" Value="LightGray"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="T_Grid" Property="Background" Value="#FFC1C1C1"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
View Code

3、窗口 resize 鼠标*改变窗口大小 (转)

覆写一个OnSourceInitialized方法,在其中添加一个委托

WPF 自定义窗口WPF 自定义窗口
        //重写
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource
= PresentationSource.FromVisual(this) as HwndSource;
if (hwndSource != null)
{
hwndSource.AddHook(
new HwndSourceHook(WndProc));
}
}

private const int WM_NCHITTEST = 0x0084;
private Point mousePoint = new Point(); //鼠标坐标
private const int ResizeBorderAGWidth = 12;//转角宽度
private const int ResizeBorderThickness = 4;//边框宽度
/// <summary>
/// 委托方法
/// </summary>
/// <param name="hwnd"></param>
/// <param name="msg"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <param name="handled"></param>
/// <returns></returns>
protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case WM_NCHITTEST:
mousePoint.X
= (lParam.ToInt32() & 0xFFFF);
mousePoint.Y
= (lParam.ToInt32() >> 16);
// 窗口左上角
if (mousePoint.Y - Top <= ResizeBorderAGWidth && mousePoint.X - Left <= ResizeBorderAGWidth)
{
handled
= true;
return new IntPtr((int)HitTest.HTTOPLEFT);
}
// 窗口左下角  
else if (ActualHeight + Top - mousePoint.Y <= ResizeBorderAGWidth && mousePoint.X - Left <= ResizeBorderAGWidth)
{
handled
= true;
return new IntPtr((int)HitTest.HTBOTTOMLEFT);
}
// 窗口右上角
else if (mousePoint.Y - Top <= ResizeBorderAGWidth && ActualWidth + Left - mousePoint.X <= ResizeBorderAGWidth)
{
handled
= true;
return new IntPtr((int)HitTest.HTTOPRIGHT);
}
// 窗口右下角
else if (ActualWidth + Left - mousePoint.X <= ResizeBorderAGWidth && ActualHeight + Top - mousePoint.Y <= ResizeBorderAGWidth)
{
handled
= true;
return new IntPtr((int)HitTest.HTBOTTOMRIGHT);
}
// 窗口左侧
else if (mousePoint.X - Left <= ResizeBorderThickness)
{
handled
= true;
return new IntPtr((int)HitTest.HTLEFT);
}
// 窗口右侧
else if (ActualWidth + Left - mousePoint.X <= ResizeBorderThickness)
{
handled
= true;
return new IntPtr((int)HitTest.HTRIGHT);
}
// 窗口上方
else if (mousePoint.Y - Top <= ResizeBorderThickness)
{
handled
= true;
return new IntPtr((int)HitTest.HTTOP);
}
// 窗口下方
else if (ActualHeight + Top - mousePoint.Y <= ResizeBorderThickness)
{
handled
= true;
return new IntPtr((int)HitTest.HTBOTTOM);
}
else // 窗口移动
{
//handled = true;
//return new IntPtr((int)HitTest.HTCAPTION);
return IntPtr.Zero;
}
}

return IntPtr.Zero;
}
View Code

用到的枚举列表类:

WPF 自定义窗口WPF 自定义窗口
public enum HitTest : int
{
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,
}
View Code