WPF创建自定义窗体
2011-06-28 12:06
399 查看
使用wpf能够轻松的制作华丽炫目的程序界面,但是其默认的窗体样式太死板,在win7下看起来还不错,在xp或2003下却显得很不协调;因此我们需要自定义窗体样式,wpf应该如何自定义窗体呢?
最开始我想到的方法,也是最传统的方法,就是是使用模板和样式来自定义窗体,首先设置窗体的WindowStyle为None,然后在Template里定义窗体布局,还需要考虑标题栏拖动、双击最大化、右键系统菜单、窗体操作按钮,然后就是Resize边框的放大,缩小,最后我也实现所有功能,但是也许我是个完美主义者,发现windows自带的窗体Resize边框拖动的时候会有虚线框,而我的方法却是随鼠标移动而改变大小,于是又开始在google上找相关资料,终于找到最好用也是最高效的方法,就是通过wpfshell
library的WindowChrome来实现,下面都是介绍如何使用WindowChrome创建自定义窗体。
最新的wpfshelllibrary(v3.5)包含在微软发布的MicrosoftRibbonforWPF中,下载后安装即可在项目中添加Microsoft.Windows.Shell引用;当然可以直接下载WPF
ShellIntegrationLibrary,包含源代码,这里只介绍其中WindowChrome的用法,想知道更多功能或者WindowChrome如何实现的可以下载源码来自己研究。
下面将由浅到深介绍如何使用WindowChrome创建自定义窗体:
前提条件:下载并安装MicrosoftRibbonforWPF
开发环境:VS2010/Blend4、VS2008
相关技术:WPF基础、样式和模板、依赖项属性、附加属性、WPF
中的路由事件和命令
示例一:Win7下透明玻璃窗体
1、首先下载并安装MicrosoftRibbonforWPF
2、打开Vs2010,选择创建WPF应用程序项目(注意在windows项目列表中我们会发现多了一个模板WPFRibbonApplication,但是这里我们并不讨论如何使用Ribbon,仍然选择WPF应用程序)
3、添加项目引用,在.net引用列表中选择Microsoft.Windows.Shell,如图:
如果选择你使用WPFShellIntegrationLibrary,则需要在浏览标签项里选择Microsoft.Windows.Shell所在的位置
4、为了体现区别,我们分别创建不同类型的子窗体来做实例,首先创建新的wpf窗体Windows1,在xaml中添加Shell命名空间引用
5、接着复制以下代码到Window定义中:
这里的WindowChrome实际上是一个附加属性,通过它对设置Window的属性,具体实现参考Shell源码WPFShellIntegrationLibrary,WindowChrome的第一个属性GlassFrameThickness是玻璃效果区域的高度,只有在开启了Aero的玻璃效果才能看到,否则是系统默认的效果,GlassFrameThickness设置为-1表示对整个窗体起用玻璃效果;ResizeBorderThickness是Resize边框的宽度;CaptionHeight是标题区域的高度,也就是窗体的操作区域,比如右键系统菜单,操作按钮,双击最大化还原等;CornerRadius是设置窗体的边角的弧度。
加了这段代码后窗体就能实现点击标题拖动,右键系统菜单,最大化,还原,拖动Resize边框改变窗体大小,这样就包含自定义窗体必须包含的最重要的要素,但是此时运行程序,我们发现整个窗体都是白色的,并没有玻璃背景的效果,因为wpf窗体默认的背景是白色的,覆盖了WindowChrome的效果,要解决很简单,自定义Window的Template,在xaml中添加以下代码:
在Win7下运行后,效果如下:
怎么样,是不是很简单,当然win7下才有这种效果,xp或2003中会显示为空白,为解决这个问题,下面我们再看看下面这个示例:
示例二:通用的窗体
在示例1的基础上添加Wpf窗体Window2,添加Shell命名空间和WindowChrome定义:
这里我们将GlassFrameThickness设置为0,也就是去掉玻璃窗体效果,我们需要自己定义窗体显示样式,首先我们必须模拟win7下的透明玻璃效果,因为本人缺少一定的美工底子,这里我用半透明颜色来代替玻璃效果,要让wpf支持透明背景,我们必须将窗体的WindowStyle设置为"None",同时必须将AllowsTransparency设置为True(注意不能单独设置AllowsTransparency为true,必须在WindowStyle="None"前提下)
接着在xaml中添加如下代码:
这样我们的窗体就具有了半透明背景,但是窗体操作的按钮没有了,需要我们自己添加按钮,注意在CaptionHeight区域定义按钮必须将其IsHitTestVisibleInChrome设置为True,否则它将变得不可点击;这里我们添加一个关闭的按钮,按钮的Command绑定到路由命令shell:SystemCommands.CloseWindowCommand,因此需要给窗体绑定路由命令,在xaml中添加如下代码:
在xaml.cs中添加事件处理方法:
这样我们点击关闭按钮,就可以触发OnCloseWindowCommand路由事件,在事件处理方法中关闭窗体,如果你不明白什么是路由命令,参考了解WPF中的路由事件和命令;
OK,现在我们在Aero特效和无特效情况下运行得到同样的效果:
示例三:创建窗体控件库
方便起见,这里我直接使用我在项目中创建好的自定义窗体控件,窗体外观都在样式模板中定义,我们可以根据需要修改窗体样式,自定义控件使用方法:
首先在帖子最下方下载示例程序,在SimpleWindowChrome项目中添加CustomControl引用,然后添加wpf窗体window3,修改window3.xaml如下:
至于自定义控件部分,这里就不贴代码了,大家可以帖子下方下载示例程序,关键地方我都在代码中有注释;
运行程序截图:
示例中我尽可能多的使用xmal完成所需的功能,而尽量避免过多的后台代码,因此对于初学wpf或者不习惯xaml者造成阅读困难,但是我觉得xaml才是wpf的精髓所在,不明白者需要耐心阅读,多上google查找相关资料,本文示例下载:
http://download.csdn.net/source/3242566
更新下载VS2008版本示例,由于wpf3存在一个公所周知的Bug,就是在Style中不能设置Content的值,因此相对vs2010版本有一点点小改动,我在CaptionButton基类中添加了一个ControlTemplate类型的依赖项属性,在CaptionButton继承类对象中通过对ControlTemplate的设置来达到与设置Content同样的效果,VS2008版本示例下载地址:
http://download.csdn.net/source/3243089
原文地址:http://blog.csdn.net/duanzilin/archive/2011/05/02/6385151.aspx
最开始我想到的方法,也是最传统的方法,就是是使用模板和样式来自定义窗体,首先设置窗体的WindowStyle为None,然后在Template里定义窗体布局,还需要考虑标题栏拖动、双击最大化、右键系统菜单、窗体操作按钮,然后就是Resize边框的放大,缩小,最后我也实现所有功能,但是也许我是个完美主义者,发现windows自带的窗体Resize边框拖动的时候会有虚线框,而我的方法却是随鼠标移动而改变大小,于是又开始在google上找相关资料,终于找到最好用也是最高效的方法,就是通过wpfshell
library的WindowChrome来实现,下面都是介绍如何使用WindowChrome创建自定义窗体。
最新的wpfshelllibrary(v3.5)包含在微软发布的
ShellIntegrationLibrary,包含源代码,这里只介绍其中WindowChrome的用法,想知道更多功能或者WindowChrome如何实现的可以下载源码来自己研究。
下面将由浅到深介绍如何使用WindowChrome创建自定义窗体:
前提条件:下载并安装
开发环境:VS2010/Blend4、VS2008
相关技术:
中的路由事件和命令
示例一:Win7下透明玻璃窗体
1、首先下载并安装
2、打开Vs2010,选择创建WPF应用程序项目(注意在windows项目列表中我们会发现多了一个模板WPFRibbonApplication,但是这里我们并不讨论如何使用Ribbon,仍然选择WPF应用程序)
3、添加项目引用,在.net引用列表中选择Microsoft.Windows.Shell,如图:
如果选择你使用
4、为了体现区别,我们分别创建不同类型的子窗体来做实例,首先创建新的wpf窗体Windows1,在xaml中添加Shell命名空间引用
< Window x:Class ="SimpleWindowChrome.Window2"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell ="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell"
Title ="Window2" Height ="300" Width ="300" >
5、接着复制以下代码到Window定义中:
< shell:WindowChrome.WindowChrome >
< shell:WindowChrome GlassFrameThickness ="-1" ResizeBorderThickness ="4"
CaptionHeight ="28" CornerRadius ="0" />
shell:WindowChrome.WindowChrome >
这里的WindowChrome实际上是一个附加属性,通过它对设置Window的属性,具体实现参考Shell源码
加了这段代码后窗体就能实现点击标题拖动,右键系统菜单,最大化,还原,拖动Resize边框改变窗体大小,这样就包含自定义窗体必须包含的最重要的要素,但是此时运行程序,我们发现整个窗体都是白色的,并没有玻璃背景的效果,因为wpf窗体默认的背景是白色的,覆盖了WindowChrome的效果,要解决很简单,自定义Window的Template,在xaml中添加以下代码:
< Window.Template >
< ControlTemplate TargetType ="{x:TypeWindow}" >
< Border BorderThickness ="1" >
< DockPanel >
< Grid x:Name ="WindowHeader" DockPanel .Dock ="Top" Height ="25" >
< TextBlock Text ="{TemplateBindingTitle}" />
Grid >
< ContentPresenter Margin ="20,20,20,20" />
DockPanel >
Border >
ControlTemplate >
Window.Template >
在Win7下运行后,效果如下:
怎么样,是不是很简单,当然win7下才有这种效果,xp或2003中会显示为空白,为解决这个问题,下面我们再看看下面这个示例:
示例二:通用的窗体
在示例1的基础上添加Wpf窗体Window2,添加Shell命名空间和WindowChrome定义:
< shell:WindowChrome.WindowChrome >
< shell:WindowChrome GlassFrameThickness ="0" ResizeBorderThickness ="4"
CaptionHeight ="28" CornerRadius ="0" />
shell:WindowChrome.WindowChrome >
这里我们将GlassFrameThickness设置为0,也就是去掉玻璃窗体效果,我们需要自己定义窗体显示样式,首先我们必须模拟win7下的透明玻璃效果,因为本人缺少一定的美工底子,这里我用半透明颜色来代替玻璃效果,要让wpf支持透明背景,我们必须将窗体的WindowStyle设置为"None",同时必须将AllowsTransparency设置为True(注意不能单独设置AllowsTransparency为true,必须在WindowStyle="None"前提下)
接着在xaml中添加如下代码:
< Window.Template >
< ControlTemplate TargetType ="{x:TypeWindow}" >
< Border BorderThickness ="1" BorderBrush ="Black" Background ="#CC6C779A" >
< DockPanel >
< Grid x:Name ="WindowHeader" DockPanel .Dock ="Top" Height ="25" >
< DockPanel >
< Button DockPanel .Dock ="Right" Foreground ="Black"
shell:WindowChrome . IsHitTestVisibleInChrome ="True"
Command ="{x:Staticshell:SystemCommands.CloseWindowCommand}"
Background ="{x:Null}" BorderBrush ="{x:Null}"
FontSize ="16" Width ="20" Content ="X" />
< TextBlock Text ="{TemplateBindingTitle}" />
</ DockPanel >
</ Grid >
< ContentPresenter s/>
</ DockPanel >
</ Border >
</ ControlTemplate >
</ Window.Template >
这样我们的窗体就具有了半透明背景,但是窗体操作的按钮没有了,需要我们自己添加按钮,注意在CaptionHeight区域定义按钮必须将其IsHitTestVisibleInChrome设置为True,否则它将变得不可点击;这里我们添加一个关闭的按钮,按钮的Command绑定到路由命令shell:SystemCommands.CloseWindowCommand,因此需要给窗体绑定路由命令,在xaml中添加如下代码:
< Window.CommandBindings >
< CommandBinding Command ="{x:Staticshell:SystemCommands.CloseWindowCommand}"
Executed ="_OnCloseWindowCommand" />
</ Window.CommandBindings >
在xaml.cs中添加事件处理方法:
private void _OnCloseWindowCommand(object sender,ExecutedRoutedEventArgse)
{
Window_window=Window.GetWindow(this );
Microsoft.Windows.Shell.SystemCommands.CloseWindow(_window);
}
这样我们点击关闭按钮,就可以触发OnCloseWindowCommand路由事件,在事件处理方法中关闭窗体,如果你不明白什么是路由命令,参考
OK,现在我们在Aero特效和无特效情况下运行得到同样的效果:
示例三:创建窗体控件库
方便起见,这里我直接使用我在项目中创建好的自定义窗体控件,窗体外观都在样式模板中定义,我们可以根据需要修改窗体样式,自定义控件使用方法:
首先在帖子最下方下载示例程序,在SimpleWindowChrome项目中添加CustomControl引用,然后添加wpf窗体window3,修改window3.xaml如下:
<controls:CustomChromeWindowxmlns:controls="clr-namespace:CustomControl;assembly=CustomControl"
x:Class="SimpleWindowChrome.Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation
"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml
"
Title="Window3"Height="300"Width="300"
CornerRadius="10,10,5,5">
<StackPanelHorizontalAlignment="Center"VerticalAlignment="Center">
<TextBlockTextWrapping="Wrap"Width="250"FontSize="15">
<TextBlock.Text>
引用自定义窗体控件,可以在WIN7/XP/2003上查看
</TextBlock.Text>
</TextBlock>
</StackPanel>
</controls:CustomChromeWindow>
至于自定义控件部分,这里就不贴代码了,大家可以帖子下方下载示例程序,关键地方我都在代码中有注释;
运行程序截图:
示例中我尽可能多的使用xmal完成所需的功能,而尽量避免过多的后台代码,因此对于初学wpf或者不习惯xaml者造成阅读困难,但是我觉得xaml才是wpf的精髓所在,不明白者需要耐心阅读,多上google查找相关资料,本文示例下载:
更新下载VS2008版本示例,由于wpf3存在一个公所周知的Bug,就是在Style中不能设置Content的值,因此相对vs2010版本有一点点小改动,我在CaptionButton基类中添加了一个ControlTemplate类型的依赖项属性,在CaptionButton继承类对象中通过对ControlTemplate的设置来达到与设置Content同样的效果,VS2008版本示例下载地址:
原文地址:
相关文章推荐
- WPF 创建自定义窗体
- WPF:使用VS2015 创建自定义项模板
- WPF创建不规则窗体并实现阴影效果
- WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox
- WPF 自定义Metro Style窗体
- WPF中自定义窗体标题栏
- 在Delphi 中用程序实现自定义窗体的创建和显示顺序(1)
- WPF 去除系统窗体边框,自定义移动窗体
- WPF创建自定义按钮[2]
- WPF窗体自定义基类
- Wpf和WinForm在窗体中处理用户自定义消息的不同方式
- WPF 之 自定义窗体标题栏
- WPF 自定义Metro Style窗体
- [WPF] 自定义窗体样式
- WPF 去边框 自定义窗体 拖动窗体大小变化
- 在Delphi 中用程序实现自定义窗体的创建和显示顺序(2)
- wpf打开自己创建窗体中的超链接
- WPF中自定义窗体标题栏
- WPF 自定义Metro Style窗体
- WPF自定义窗体仿新毒霸关闭特效(只能在自定义窗体中正常使用)