WPF自定义控件(三)——Window
一样!先来看看效果吧:

怎么样?效果很好吧,而且不只是样式哟!所有系统窗体有的交互操作都可以实现!
但可惜。。。有很多和系统API有关的东西本人了解得并不多,所以这个窗体是基于他人的成果上产生的。关于窗体交互的东西还是看看原作者的吧:
http://blog.csdn.net/dlangu0393/article/details/12548731
接下来说说我在这上面多加的功能:可设置标题栏可见性,可扩展标题栏下拉按钮,可全屏并拦截键盘,另外还多公布了一些属性
再来一张图:

这就是没有标题栏的,只是设置一个属性就可以了哟!
废话不多说了!再来看看我代码,只发一些我加了的吧,上面的链接里有的我就不发了,想看完整的,之后我会发源码的。
先是Xaml的:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrl="clr-namespace:KAN.WPF.XCtrl.Controls" >
<Style x:Key="XWindowStyle" TargetType="ctrl:XWindow">
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="WindowStyle" Value="None"/>
<!--解决图片模糊-->
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="RenderOptions.BitmapScalingMode" Value="NearestNeighbor" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<!--改字体-->
<Setter Property="FontFamily" Value="Microsoft YaHei" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrl:XWindow">
<Border x:Name="bdrWindow" CornerRadius="5" Margin="8" Background="White"
BorderBrush="#6A6A6A" BorderThickness="1" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" >
<Border.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" Color="#00000000"/>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Name="bdrTitleBar" Height="28" CornerRadius="5,5,0,0" Panel.ZIndex="10" >
<Border.Background>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndTitleBar.png" />
</Border.Background>
<DockPanel Margin="0" >
<Image DockPanel.Dock="Left" Name="imgIcon" VerticalAlignment="Top" Width="15" Height="15"
Margin="5 5 0 0" Source="{TemplateBinding Icon}" Style="{DynamicResource ImgIconStyle}">
</Image>
<TextBlock DockPanel.Dock="Left" Name="txbTitle" VerticalAlignment="Top"
Margin="5 5 0 0" FontSize="12" FontWeight="Bold" Foreground="#FF101010" Text="{TemplateBinding Title}" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"
DockPanel.Dock="Right" Height="28" VerticalAlignment="Top">
<ctrl:XButton x:Name="btnDropDown" Width="28" Height="28" BorderThickness="0" Visibility="Collapsed">
<ctrl:XButton.Background>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnDropDown.png" />
</ctrl:XButton.Background>
<ctrl:XButton.XMoverBrush>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnDropDownMove.png" />
</ctrl:XButton.XMoverBrush>
<ctrl:XButton.XEnterBrush>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnDropDownMove.png" />
</ctrl:XButton.XEnterBrush>
</ctrl:XButton>
<ctrl:XButton x:Name="btnMin" Width="28" Height="28" BorderThickness="0" >
<ctrl:XButton.Background>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnMin.png" />
</ctrl:XButton.Background>
<ctrl:XButton.XMoverBrush>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnMinMove.png" />
</ctrl:XButton.XMoverBrush>
<ctrl:XButton.XEnterBrush>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnMinEnter.png" />
</ctrl:XButton.XEnterBrush>
</ctrl:XButton>
<ctrl:XButton x:Name="btnMax" Width="28" Height="28" BorderThickness="0" >
<ctrl:XButton.Background>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnMax.png" />
</ctrl:XButton.Background>
<ctrl:XButton.XMoverBrush>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnMaxMove.png" />
</ctrl:XButton.XMoverBrush>
<ctrl:XButton.XEnterBrush>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnMaxEnter.png" />
</ctrl:XButton.XEnterBrush>
</ctrl:XButton>
<ctrl:XButton x:Name="btnClose" Width="28" Height="28" BorderThickness="0" >
<ctrl:XButton.Background>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnClose.png" />
</ctrl:XButton.Background>
<ctrl:XButton.XMoverBrush>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnCloseMove.png" />
</ctrl:XButton.XMoverBrush>
<ctrl:XButton.XEnterBrush>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndBtnCloseEnter.png" />
</ctrl:XButton.XEnterBrush>
</ctrl:XButton>
</StackPanel>
</DockPanel>
</Border>
<!--标题栏下的阴影-->
<AdornerDecorator Grid.Row="1" Height="Auto" Width="Auto">
<Grid>
<Border Name="bdrShadow" Height="5" VerticalAlignment="Top" Panel.ZIndex="100" HorizontalAlignment="Stretch">
<Border.Background>
<ImageBrush ImageSource="/KAN.WPF.Xctrl;component/Images/XWindow/WndTitleShadow.png" />
</Border.Background>
</Border>
<ContentPresenter/>
</Grid>
</AdornerDecorator>
</Grid>
</Border>
<ControlTemplate.Triggers>
<!--根据设置,隐藏最大、最小化按钮-->
<Trigger Property="ResizeMode" Value="NoResize">
<Setter TargetName="btnMin" Property="Visibility" Value="Collapsed"></Setter>
<Setter TargetName="btnMax" Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<Trigger Property="ResizeMode" Value="CanMinimize">
<Setter TargetName="btnMax" Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<!--是否显示标题栏-->
<Trigger Property="XIsShowBdrTitleBar" Value="false">
<Setter TargetName="bdrTitleBar" Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<!--是否显示下拉按钮-->
<Trigger Property="XIsShowBtnDropDown" Value="true">
<Setter TargetName="btnDropDown" Property="Visibility" Value="Visible"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
还有CS的:
/// <summary>
/// 静态构造方法
/// </summary>
static XWindow()
{
XWindow.XIsShowBdrTitleBarProperty = DependencyProperty.Register("XIsShowBdrTitleBar", typeof(bool), typeof(XWindow),
new PropertyMetadata(true));
XWindow.XIsShowBtnDropDownProperty = DependencyProperty.Register("XIsShowBtnDropDown", typeof(bool), typeof(XWindow),
new PropertyMetadata(false));
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(XWindow), new FrameworkPropertyMetadata(typeof(XWindow)));
}
/////////////////////////////////////////////////////////////////////////////////// public void InitializeEvent()
{ //解决没有图标时标题不顶头问题
if (imgIcon.Source == null)
{
imgIcon.Visibility = Visibility.Collapsed;
} //防止窗体一启动时就最大化引发的边框和按钮问题
if (WindowState == WindowState.Maximized)
{
bdrWindow.Margin = new Thickness();
ImageBrush img = new ImageBrush();
ImageBrush imgE = new ImageBrush();
ImageBrush imgM = new ImageBrush();
img.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnRestore.png"));
btnMax.Background = img;
imgE.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnRestoreEnter.png"));
btnMax.XEnterBrush = imgE;
imgM.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnRestoreMove.png"));
btnMax.XMoverBrush = imgM;
}
else
{
bdrWindow.Margin = new Thickness(customMargin);
ImageBrush img = new ImageBrush();
ImageBrush imgE = new ImageBrush();
ImageBrush imgM = new ImageBrush();
img.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnMax.png"));
btnMax.Background = img;
imgE.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnMaxEnter.png"));
btnMax.XEnterBrush = imgE;
imgM.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnMaxMove.png"));
btnMax.XMoverBrush = imgM;
} //最小化窗体
btnMin.Click += delegate
{
this.WindowState = WindowState.Minimized;
}; //最大化窗体
btnMax.Click += delegate
{
if (this.WindowState == WindowState.Maximized)
{
this.WindowState = WindowState.Normal;
}
else
{
this.WindowState = WindowState.Maximized;
}
}; //关闭窗体
btnClose.Click += delegate
{
Exit();
}; //双击标题栏最大化窗体
bdrTitleBar.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
{
if ((e.ClickCount >= && ResizeMode == System.Windows.ResizeMode.CanResize))
{
btnMax.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
}
}; //
bdrTitleBar.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
{
Window_MouseLeftButtonDown(sender, e);
};
}
//////////////////////////////////////////////////////////////////////// /// <summary>
/// 处理最大化时阴影边框问题,和最大化按钮变化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Window_StateChanged(object sender, EventArgs e)
{
if (WindowState == WindowState.Maximized)
{
bdrWindow.Margin = new Thickness();
ImageBrush img = new ImageBrush();
ImageBrush imgE = new ImageBrush();
ImageBrush imgM = new ImageBrush();
img.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnRestore.png"));
btnMax.Background = img;
imgE.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnRestoreEnter.png"));
btnMax.XEnterBrush = imgE;
imgM.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnRestoreMove.png"));
btnMax.XMoverBrush = imgM;
}
else
{
bdrWindow.Margin = new Thickness(customMargin);
ImageBrush img = new ImageBrush();
ImageBrush imgE = new ImageBrush();
ImageBrush imgM = new ImageBrush();
img.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnMax.png"));
btnMax.Background = img;
imgE.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnMaxEnter.png"));
btnMax.XEnterBrush = imgE;
imgM.ImageSource = new BitmapImage(new Uri("pack://application:,,,/KAN.WPF.Xctrl;Component/Images/XWindow/WndBtnMaxMove.png"));
btnMax.XMoverBrush = imgM;
}
}
//////////////////////////////////////////////////////////////////// /// <summary>
/// 键盘捕捉
/// </summary>
/// <param name="hookStruct"></param>
/// <param name="handle"></param>
public void OnKeyPress(Hook.HookStruct hookStruct, out bool handle)
{
//默认不屏蔽
handle = false; //屏蔽键Win
if (hookStruct.vkCode == (int)WinForms.Keys.LWin || hookStruct.vkCode == (int)WinForms.Keys.RWin)
{
handle = true;
} } ////////////////////////////////////////////////////////////////////////
#region 公布方法
/// <summary>
/// 进入全屏
/// </summary>
public void XFullScreen()
{
//解决最大化后,全屏不覆盖任务栏的问题
this.WindowState = WindowState.Normal;
bdrTitleBar.Visibility = Visibility.Collapsed;
bdrWindow.Margin = new Thickness(); this.ResizeMode = System.Windows.ResizeMode.NoResize; this.Left = 0.0;
this.Top = 0.0;
this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
this.Height = System.Windows.SystemParameters.PrimaryScreenHeight; //屏蔽鼠标拖动
this.MouseLeftButtonDown -= new MouseButtonEventHandler(Window_MouseLeftButtonDown); //安装钩子
keyboardHook = new Hook();
keyboardHook.InstallHook(this.OnKeyPress);
} /// <summary>
/// 退出全屏
/// </summary>
public void XExitFullScreen(double width, double height, double x, double y)
{
bdrTitleBar.Visibility = Visibility.Visible;
bdrWindow.Margin = new Thickness(customMargin); //窗体恢复位置
this.ResizeMode = ResizeMode.CanResize;
this.WindowState = WindowState.Normal;
this.Width = width;
this.Height = height;
this.Left = x;
this.Top = y; //添加鼠标拖动事件
this.MouseLeftButtonDown += new MouseButtonEventHandler(Window_MouseLeftButtonDown); //取消钩子
keyboardHook.UninstallHook();
} /// <summary>
/// 退出方法
/// </summary>
public virtual void Exit()
{
this.Close();
}
#endregion #region 公布属性
/// <summary>
/// 公布属性XIsShowBdrTitleBar(是否显示标题栏)
/// </summary>
public bool XIsShowBdrTitleBar
{
get
{
return (bool)base.GetValue(XWindow.XIsShowBdrTitleBarProperty);
}
set
{
base.SetValue(XWindow.XIsShowBdrTitleBarProperty, value);
}
} /// <summary>
/// 公布属性XIsShowBtnDropDown(是否显示下拉按钮)
/// </summary>
public bool XIsShowBtnDropDown
{
get
{
return (bool)base.GetValue(XWindow.XIsShowBtnDropDownProperty);
}
set
{
base.SetValue(XWindow.XIsShowBtnDropDownProperty, value);
}
}
#endregion #region 重写方法
/// <summary>
/// 应用样式
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
btnMin = GetTemplateChild("btnMin") as XButton;
btnMax = GetTemplateChild("btnMax") as XButton;
btnClose = GetTemplateChild("btnClose") as XButton;
btnDropDown = GetTemplateChild("btnDropDown") as XButton;
imgIcon = GetTemplateChild("imgIcon") as Image;
bdrWindow = GetTemplateChild("bdrWindow") as Border;
bdrTitleBar = GetTemplateChild("bdrTitleBar") as Border;
}
#endregion
好啦!太多了,有点乱是吧!待会我把源码发上来吧!大家看看!多多提意见啊!
WPF自定义控件(三)——Window的更多相关文章
- WPF自定义控件三:消息提示框
需求:实现全局消息提示框 一:创建全局Message public class Message { private static readonly Style infoStyle = (Style)A ...
- WPF自定义控件(三)
今天我们开始制作我们的按钮,主要的效果就是一个按钮正常状态.鼠标滑过.按下三态显示不同的图片. 首先我们需要给扩展按钮添加三个属性,分别是正常状态图片,鼠标滑过图片,按钮按下图片. 先贴出Button ...
- WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 自定义 ...
- 【转】WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: 自定义Window窗体样式: 基于自定义窗体实现自定义MessageB ...
- [WPF自定义控件]?使用WindowChrome自定义Window Style
原文:[WPF自定义控件]?使用WindowChrome自定义Window Style 1. 为什么要自定义Window 对稍微有点规模的桌面软件来说自定义的Window几乎是标配了,一来设计师总是克 ...
- [WPF自定义控件]?Window(窗体)的UI元素及行为
原文:[WPF自定义控件]?Window(窗体)的UI元素及行为 1. 前言 本来打算写一篇<自定义Window>的文章,但写着写着发觉内容太多,所以还是把使用WindowChrome自定 ...
- WPF自定义控件(三)の扩展控件
扩展控件,顾名思义就是对已有的控件进行扩展,一般继承于已有的原生控件,不排除继承于自定义的控件,不过这样做意义不大,因为既然都自定义了,为什么不一步到位呢,有些不同的需求也可以通过此来完成,不过类似于 ...
- WPF自定义控件与样式(1)-矢量字体图标(iconfont)
一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...
- WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要有三种实现方式 ...
- WPF自定义控件与样式(14)-轻量MVVM模式实践
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. MVVM是WPF中一个非 ...
随机推荐
- 【python,threading】python多线程
使用多线程的方式 1. 函数式:使用threading模块threading.Thread(e.g target name parameters) import time,threading def ...
- TQ210开发板NFS挂载android4.0.4的rootfs的方法
首先声明的是,我使用的u-boot是自己移植的u-boot2013.01.01而非天嵌官方的那个,至于使用官方的u-boot如何去实现nfs挂载rootfs我没怎么研究过,不过原理方法都是一致的. 主 ...
- mac下修改mysql登录密码
mysql版本5.7.9 在mac终端下修改mysql用户登录密码 终端命令如下: update mysql.user set authentication_string=PASSWORD(" ...
- oracle PL/SQL(procedure language/SQL)程序设计之游标cursors
游标 Cursors--Conception 每一条被Oracle服务器执行的SQL语句都有一个独立的游标与之相关联:隐式游标 Implicit cursors: 用于所有的DML和PL/SQL的SE ...
- 服务器调用JS
服务器控件调用JS一.两类JS的触发设计1.提交之前的JS -- 加js的事件例:<script language="javascript"> // 构造函数 func ...
- 使用c#将多个文件放入文件夹中,并压缩下载
ZipClass.cs 这个是一个压缩文件的类,可直接复制使用,使用到的命名空间是 using System.IO;using ICSharpCode.SharpZipLib;using ICSha ...
- JVM内存分配
内存分配:当JVM运行起来的时候就会给内存划分空间,那么这块空间称之为运行时数据区.(备注:当一个Java源程序编译成class字节码文件之后,字节码文件里存放的都是二进制的汇编命令,当程序运行的时候 ...
- Java中的toString()方法
Java中的toString()方法 目录 Java中的toString()方法 1. 对象的toString方法 2. 基本类型的toString方法 3. 数组的toString ...
- Codevs 1092 不高兴的津津
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 津津上初中了.妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参 ...
- ServletContext的用途
安装在一个服务器中的一个特定URL名字空间(比如,/myapplication)下的所有Servlet,JSP,JavaBean等Web部件的集合构成了一个Web的应用,每一个Web应用(同一JVM) ...