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中一个非 ...
随机推荐
- TFS 2010 使用手册(三)权限管理
本文参考了 蔚蓝的宁静 http://www.cnblogs.com/tymo/archive/2011/03/21/1990550.html 等文章. 1.权限说明 1.1 权限关联 TFS的权限与 ...
- Java协变返回类型
今天看到句话:“支持重写方法时返回协变类型”. 那么什么事协变类型?在网上找了找资料,大体上明白了. Java 5.0添加了对协变返回类型的支持,即子类覆盖(即重写)基类方法时,返回的类型可以是基类方 ...
- 《MFC游戏开发》笔记六 图像双缓冲技术:实现一个流畅的动画
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9334121 作者:七十一雾央 新浪微博:http:/ ...
- P1111 修复公路
P1111 修复公路 550通过 1.6K提交 题目提供者该用户不存在 标签并查集 难度普及/提高- 提交该题 讨论 题解 记录 题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通 ...
- javascript事件代理(委托)
之前有接触过事件代理,但是印象并不深刻.这次记下来加强印象. 用个大家比较常见的代码举例子: html dom结构: <ul id="ul1"> <li>0 ...
- C++类(一)
#include<iostream> #include<string> using namespace std; //找了很久,似乎都是类放在Main方法体上 class Pe ...
- CSS之隐藏元素
1.opacity=0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定一些事件,如click事件,那么点击该区域,也能触发点击事件的2.visibility=hidden,该元素隐藏起 ...
- C#调用SSIS包及读取DataReader目标
C#调用SSIS包需要引用两个DLL .(具体位置在C盘搜索,MSDN和百度提供的路径都不太正确) Microsoft.SQLServer.ManagedDTS.dll Microsoft.SqlSe ...
- Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法
http://www.cnblogs.com/SkyD/archive/2010/11/08/1871423.html Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法 Surfa ...
- Linux中RM快速删除大量文件/文件夹方法
昨天遇到一个问题,在Linux中有一个文件夹里面含有大量的Cache文件(夹),数量级可能在百万级别,使用rm -rf ./* 删除时间慢到不可接受.Google了一下,查到了一种方法,试用了下确实比 ...