WPF 自定义窗口
在WPF中,经常需要对窗口进行设置,下面讲讲常用的几个设置。
窗口样式
1、无边框窗口
无边框透明窗体 设置
WindowStyle="None"--无边框,如果需要其它按钮,如缩小、放大、收缩、关闭按钮,可以自定义
AllowsTransparency="True"--只有设置了AllowsTransparency,才有1、窗体真正的隐藏边框2、背景透明有效
Background="Transparent"
窗口阴影设置
可以用Border的CornerRadius设置窗口四周圆角
设置窗口阴影--值得一提的是,如果直接用Window.Effect,效果会影响CornerRadius设置的圆角效果。
<Window.Effect>
<DropShadowEffect BlurRadius="30" Color="Gray" ShadowDepth="0" RenderingBias="Quality" ></DropShadowEffect>
</Window.Effect>
举例:
<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>
2、窗口按钮
当我们设置无边窗口时,也即是需要重新设置一套窗口的操作按钮。
按钮,可以用修改Button的Background或者修改Template,往其中设置图标或者直接用Path、Border、Rectangle等基础元素绘制。
然后添加简单的动画Animation
1) 方法1.下面是自定义的按钮Style,往其中传入图标路径即可
<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>
2)方法2.直接用基础元素绘制
Path,通过Path来画线。当然一般水平、竖直也是可以用Rectangle/Border之类的替代
一些简单的线条图标用Path来做,还是很方便的。
<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>
3、窗口 resize 鼠标自由改变窗口大小 (转)
覆写一个OnSourceInitialized方法,在其中添加一个委托
//重写
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 = ;//转角宽度
private const int ResizeBorderThickness = ;//边框宽度
/// <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() >> );
// 窗口左上角
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;
}
用到的枚举列表类:
public enum HitTest : int
{
HTERROR = -,
HTTRANSPARENT = -,
HTNOWHERE = ,
HTCLIENT = ,
HTCAPTION = ,
HTSYSMENU = ,
HTGROWBOX = ,
HTSIZE = HTGROWBOX,
HTMENU = ,
HTHSCROLL = ,
HTVSCROLL = ,
HTMINBUTTON = ,
HTMAXBUTTON = ,
HTLEFT = ,
HTRIGHT = ,
HTTOP = ,
HTTOPLEFT = ,
HTTOPRIGHT = ,
HTBOTTOM = ,
HTBOTTOMLEFT = ,
HTBOTTOMRIGHT = ,
HTBORDER = ,
HTREDUCE = HTMINBUTTON,
HTZOOM = HTMAXBUTTON,
HTSIZEFIRST = HTLEFT,
HTSIZELAST = HTBOTTOMRIGHT,
HTOBJECT = ,
HTCLOSE = ,
HTHELP = ,
}
窗口拖动
1、在界面上对布局元素如Grid,添加委托事件: MouseLeftButtonDown="UIElement_OnMouseLeftButtonDown"
2、委托方法中处理一下就行了:
private void UIElement_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ButtonState==MouseButtonState.Pressed)
{
this.DragMove();
}
}
WPF 自定义窗口的更多相关文章
- WPF自定义窗口基类
WPF自定义窗口基类时,窗口基类只定义.cs文件,xaml文件不定义.继承自定义窗口的类xaml文件的根节点就不再是<Window>,而是自定义窗口类名(若自定义窗口与继承者不在同一个命名 ...
- WPF自学入门(九)WPF自定义窗口基类
今天简单记录一个知识点:WPF自定义窗口基类,常用winform的人知道,winform的窗体继承是很好用的,写一个基础窗体,直接在后台代码改写继承窗体名.但如果是WPF要继承窗体,我个人感觉没有理解 ...
- wpf 自定义窗口,最大化时覆盖任务栏解决方案
原文:wpf 自定义窗口,最大化时覆盖任务栏解决方案 相信很多人使用wpf时会选择自定义美观的窗口,因此会设置WindowStyle="None" 取消自带的标题栏.但这样使用 W ...
- WPF自定义窗口最大化显示任务栏
原文:WPF自定义窗口最大化显示任务栏 当我们要自定义WPF窗口样式时,通常是采用设计窗口的属性 WindowStyle="None" ,然后为窗口自定义放大,缩小,关闭按钮的样式 ...
- wpf 自定义窗口,最大化时不覆盖任务栏
相信很多人使用wpf时会选择自定义美观的窗口,因此会设置WindowStyle="None" 取消自带的标题栏.但这样使用 WindowState="Maximized& ...
- WPF 自定义窗口标题栏
1.建一个WPF资源词典,在其中定义窗口样式,并在App.xaml中指定其为程序资源 2.写一个继续自windows的类,并指定这个类的Style为第一步资源里的样式 3.新建窗口时,分别把xaml文 ...
- WPF自定义窗口(Windows Server 2012 Style)
先上图 新建CustomControl,名:HeaderedWindow Themes\Generic.aml文件夹下加入 笔刷,转换器 <SolidColorBrush x:Key=" ...
- WPF 自定义窗口关闭按钮
关闭图标设计主要涉及主要知识点: 1.Path,通过Path来画线.当然一般水平.竖直也是可以用Rectangle/Border之类的替代 一些简单的线条图标用Path来做,还是很方便的. 2.简单的 ...
- WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome)
WPF 自定义窗口样式有多种方式,不过基本核心实现都是在修改 Win32 窗口样式.然而,Windows 上的应用就应该有 Windows 应用的样子嘛,在保证自定义的同时也能与其他窗口样式保持一致当 ...
随机推荐
- ASP.NET MVC Bundle使用 合并压缩
2017-01-06 更新 在 BundleCollection 的构造函数中添加了 3种默认规则 public BundleCollection() { BundleCollection.AddDe ...
- 梯度提升树(GBDT)原理小结
在集成学习之Adaboost算法原理小结中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting De ...
- 用H5中的Canvas等技术制作海报
在去年的时候也实现过合成海报的功能,不过当时时间仓促,实现的比较简单. 就一个旋转功能,图片也不能拖动放大,也不能裁剪. 去年的实现可以参考<移动图片操作--上传>和<移动图片操作- ...
- [协议]ICMP协议剖析
1.ICMP简介 ICMP全名为(INTERNET CONTROL MESSAGE PROTOCOL)网络控制消息协议. ICMP的协议号为1. ICMP报文就像是IP报文的小弟,总顶着IP报文的名头 ...
- 从零自学Hadoop(20):HBase数据模型相关操作上
阅读目录 序 介绍 命名空间 表 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 序 ...
- 做个简单的RSS订阅(ASP.NET Core),节省自己的时间
0x01 前言 因为每天上下班路上,午休前,都是看看新闻,但是种类繁多,又要自己找感兴趣的,所以肯定会耗费不少时间. 虽说现在有很多软件也可以订阅一些自己喜欢的新闻,要安装到手机,还是挺麻烦的.所以就 ...
- .NET 实现并行的几种方式(三)
本随笔续接:.NET 实现并行的几种方式(二) 在前两篇随笔中,先后介绍了 Thread .ThreadPool .IAsyncResult (即 APM系列) .Task .TPL (Task Pa ...
- (0)ASP.NET Core 简单介绍 和开发环境搭建 - ASP.NET从MVC5升级到MVC6
ASP.NET从MVC5升级到MVC6 总目录 ASP.NET Core 首先,ASP原本只是一种技术,这种技术从上个世纪90年代就有了. Active Service Page 和 Java Ser ...
- JavaWeb_day08_EL JSTL
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day08 EL JSTL EL表达式 语法:${} ...
- PHP 策略模式
策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化.策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想 ...