《学习笔记》Layui-WPF窗体美化
一睹为快:
1.创建自定义控件,并取名为LayuiWPFStyle
2.在当前目录中创建Fonts和WindowStyle文件加用来存放字体文件和自定义窗体,字体用fontawesome字体当然你们可以用自己的自己也行
3.创建自定义控件,并取名为LayWindow,记住是WPF的别点错了
4.双击LayWindow让当前类文件继承Window
5.由于我们窗体分为头部和内容,而头部分为窗体名称和窗体图标以及窗体按钮组成
6.此时我们需要对窗体进行重绘以及添加必要的附加属性,快捷键Propdp+双击Tab,MyProperty是扩展属性名称我们可以随便定义,例如我们需要定义窗体头部栏高度我们可以定义为HearderHieght,类型为Int,ownerclass替换为当前自定义窗体的名称:LayWindow,
如图二
7.进入Generic.xaml文件中,我们会发现当我们每创建一个自定义控件时系统会默认帮我创建一个简单的Style样式,但是此时的样式时不奏效的,他只是给我们个友好的提示。此时我们需要开始从写窗体样式了,我们可以将窗体分为两份,一份为头部一分为身体(也就是内容)我们可以使用RowDefinitions进行分行,头部高度设置为自适应类容高度如图Height="auto"
8.创建一个头部栏:并且此时可以开始用上我们的自定义属性HearderHieght,切记我们自定义的属性想要生效不能用TemplateBinding(模板绑定)进行绑定必须要用Binding(数据源绑定)进行绑定如:Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}"
9.窗体内容我们用ContentPresenter进行组合使用
10.定制窗体头部,分别头部分为三列,左边分为窗体图标和窗体名称,中间预留,右边分为最大化、最小化和关闭按钮,为了方便我们统一颜色我将背景色单独抽离开
<Style TargetType="{x:Type local:LayWindow}" >
<Setter Property="Background" Value="{StaticResource WindowBackground}"/>
<Setter Property="HearderHieght" Value=""/>
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="HearderFontColor" Value="White"/>
<Setter Property="Margin" Value=""/>
<Setter Property="WindowChrome.WindowChrome" >
<Setter.Value>
<WindowChrome CaptionHeight="" ResizeBorderThickness=""/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:LayWindow}">
<Border Padding="{TemplateBinding Margin}">
<Grid>
<Grid Background="#ccc" >
<Grid.Effect>
<DropShadowEffect ShadowDepth="" Direction="" BlurRadius="" Color="#ccc">
</DropShadowEffect>
</Grid.Effect>
</Grid>
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border x:Name="WindowHearder" Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/><!--顶部颜色-->
<Grid x:Name="HearderContent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<Image Source="{TemplateBinding Icon}" VerticalAlignment="Center"/><!--窗体图标-->
<TextBlock Text="{TemplateBinding Title}" VerticalAlignment="Center" Foreground="{Binding Path=HearderFontColor,RelativeSource={RelativeSource Mode=TemplatedParent}}"/><!--窗体名称-->
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Column="">
<!--最小化按钮-->
<Button Visibility="{Binding Path=WinMinBtnVisibility,RelativeSource={RelativeSource Mode=TemplatedParent}}" Content="" x:Name="WinMinBtn" Uid=""
Style="{DynamicResource windowBtn}" Foreground="{TemplateBinding HearderFontColor}" Width="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" ToolTip="{TemplateBinding ToolTip}" />
<!--最大化按钮-->
<Button Visibility="{Binding Path=WinMaxBtnVisibility,RelativeSource={RelativeSource Mode=TemplatedParent}}" Content="" x:Name="WinMaxBtn" Uid=""
Style="{DynamicResource windowBtn}" Foreground="{TemplateBinding HearderFontColor}" Width="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" ToolTip="{TemplateBinding ToolTip}"/>
<!--关闭按钮-->
<Button Content="" RenderTransformOrigin="0.5,0.5" x:Name="WinCloseBtn" Uid="" Style="{DynamicResource windowBtn}" Foreground="{TemplateBinding HearderFontColor}"
Width="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}"
ToolTip="{TemplateBinding ToolTip}"/>
</StackPanel>
</Grid>
<ContentPresenter Grid.Row=""/>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="WinMinBtnVisibility" Value="False">
<Setter Property="Visibility" TargetName="WinMinBtn" Value="Collapsed"/>
</Trigger>
<Trigger Property="WinMaxBtnVisibility" Value="False">
<Setter Property="Visibility" TargetName="WinMaxBtn" Value="Collapsed"/>
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self},Path=WindowHearderVisibility}" Value="False">
<Setter Property="Visibility" TargetName="HearderContent" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="WindowHearder" Value="Collapsed"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
11.此时我们的Style样式写完了开始实现功能,此时我们回到LayWindow.CS文件中,实现public override void OnApplyTemplate方法,此方法时方便我们查找我们模板中的某些控件如窗体按钮
public class LayWindow : Window
{
private Button WinMaxBtn;//全局最大化按钮
private bool WinMax = true;//全局最大窗体控制
static LayWindow()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(LayWindow), new FrameworkPropertyMetadata(typeof(LayWindow)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
SizeChanged += new SizeChangedEventHandler(WindowSizeChanged);//实现窗体大小变化方法
Border WindowHearder = this.Template.FindName("WindowHearder",this) as Border;
WindowHearder.MouseLeftButtonDown += new MouseButtonEventHandler(WindowDisplacement);//注册窗体移动事件
Button WinMinBtn = this.Template.FindName("WinMinBtn", this) as Button;//查找最小化按钮
WinMinBtn.ToolTip = "最小化";//设置按钮提示名称
WinMinBtn.Click += new RoutedEventHandler(WinBtn_Click);//实现按钮点击方法
WinMaxBtn = this.Template.FindName("WinMaxBtn", this) as Button;//查找最大化按钮
WinMaxBtn.ToolTip = "最大化";//设置按钮提示名称
if (WinMaxBtn.Visibility != Visibility.Visible) WinMax = false;
WinMaxBtn.Click += new RoutedEventHandler(WinBtn_Click);//实现按钮点击方法
Button WinCloseBtn = this.Template.FindName("WinCloseBtn", this) as Button;//查找关闭按钮
WinCloseBtn.ToolTip = "关闭";//设置按钮提示名称
WinCloseBtn.Click += new RoutedEventHandler(WinBtn_Click);//实现按钮点击方法
}
/// <summary>
/// 窗体改变事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void WindowSizeChanged(object sender, SizeChangedEventArgs e)
{
Window window= sender as Window;
if (window.WindowState == WindowState.Maximized)
{
WinMaxBtn.Content = "\xf2d2";
}
else if(window.WindowState == WindowState.Normal)
{
WinMaxBtn.Content = "\xf2d0";
}
}
/// <summary>
/// 窗体按钮事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void WinBtn_Click(object sender, RoutedEventArgs e)
{
WindowStyleChange(Convert.ToInt32((sender as Button).Uid), (sender as Button).TemplatedParent as Window);
}
/// <summary>
/// 窗体状态变化
/// </summary>
/// <param name="styleCode"></param>
/// <param name="window"></param>
private void WindowStyleChange(int styleCode ,Window window) {
switch (styleCode)
{
case :
window.WindowState = WindowState.Minimized;
break;
case :
if (window.WindowState == WindowState.Maximized)
{
WinMaxBtn.Content = "\xf2d0";
WinMaxBtn.ToolTip = "最大化";
window.WindowState = WindowState.Normal;
}
else
{
WinMaxBtn.Content = "\xf2d2";
WinMaxBtn.ToolTip = "还原";
window.WindowState = WindowState.Maximized;
}
break;
case :
window.Close();
break;
}
}
/// <summary>
/// 窗体移动事件
/// </summary>
/// <param name="sender">窗体头部</param>
/// <param name="e"></param>
private void WindowDisplacement(object sender, MouseButtonEventArgs e)
{
if ((sender as Border).TemplatedParent is Window) { Window window = (sender as Border).TemplatedParent as Window;
switch (e.ClickCount)
{
case ://左键单击效果
window.DragMove();
break;
case ://左键双击效果
if(WinMax)
if (window.WindowState == WindowState.Maximized)
{
WinMaxBtn.Content = "\xf2d0";
window.WindowState = WindowState.Normal;
}
else
{
WinMaxBtn.Content = "\xf2d2";
window.WindowState = WindowState.Maximized;
}
break;
}
} }
/// <summary>
/// 窗体头部高度
/// </summary>
public int HearderHieght
{
get { return (int)GetValue(HearderHieghtProperty); }
set { SetValue(HearderHieghtProperty, value); }
} // Using a DependencyProperty as the backing store for HearderHieght. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HearderHieghtProperty =
DependencyProperty.Register("HearderHieght", typeof(int), typeof(LayWindow)); /// <summary>
/// 窗体头部字体样式
/// </summary>
public Brush HearderFontColor
{
get { return (Brush)GetValue(HearderFontColorProperty); }
set { SetValue(HearderFontColorProperty, value); }
} // Using a DependencyProperty as the backing store for HearderFontColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HearderFontColorProperty =
DependencyProperty.Register("HearderFontColor", typeof(Brush), typeof(LayWindow)); /// <summary>
/// 窗体头部栏状态
/// </summary>
public bool WindowHearderVisibility
{
get { return (bool)GetValue(WindowHearderVisibilityProperty); }
set { SetValue(WindowHearderVisibilityProperty, value); }
} // Using a DependencyProperty as the backing store for WindowHearderVisibility. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WindowHearderVisibilityProperty =
DependencyProperty.Register("WindowHearderVisibility", typeof(bool), typeof(LayWindow), new PropertyMetadata(true)); #region 窗体头部栏控制
public bool WinMinBtnVisibility
{
get { return (bool)GetValue(WinMinBtnVisibilityProperty); }
set { SetValue(WinMinBtnVisibilityProperty, value); }
} // Using a DependencyProperty as the backing store for WinMinBtnVisibility. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WinMinBtnVisibilityProperty =
DependencyProperty.Register("WinMinBtnVisibility", typeof(bool), typeof(LayWindow), new PropertyMetadata(true)); public bool WinMaxBtnVisibility
{
get { return (bool)GetValue(WinMaxBtnVisibilityProperty); }
set { SetValue(WinMaxBtnVisibilityProperty, value); }
} // Using a DependencyProperty as the backing store for WinMinBtnVisibility. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WinMaxBtnVisibilityProperty =
DependencyProperty.Register("WinMaxBtnVisibility", typeof(bool), typeof(LayWindow), new PropertyMetadata(true));
#endregion }
<FontFamily x:Key="FontFamilyStyle">/LayuiWPFStyle;component/Fonts/#FontAwesome</FontFamily>
<Style TargetType="TextBlock" >
<Setter Property="FontFamily" Value="{StaticResource FontFamilyStyle}"/>
<Setter Property="FontSize" Value=""/>
</Style>
<Style x:Key="btnBase" TargetType="Button" >
<Setter Property="Cursor" Value="Hand"/>
</Style>
<Style x:Key="windowBtn" TargetType="Button" BasedOn="{StaticResource btnBase}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value=""/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border x:Name="WindowHearder" Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
12,此时我们的自定义窗体的所有业务代码已完成,创建一个WPF项目,我们取名为Layui-WPFUI,并且引用我们刚刚做好的窗体
13.窗机WPF项目中的App.xaml文件添加自定义控件的相关样式文件
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/LayuiWPFStyle;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
14.点击MainWindow将原来的左上角的Window替换为Lay:LayWindow,并且引用xmlns:Lay="clr-namespace:LayuiWPFStyle;assembly=LayuiWPFStyle"如图
16.按F7进入后台代码让MainWindow继承我们的LayWindow
17.此时我们的自定义窗体就完成啦,点击运行就得到我们的美化后的窗体(顶部左侧的Ico图标可忽略自己也可以添加一个Ico图标)
注意:如若你的项目运行出错很有可能你的Generic.xaml文件里面有文字注释,上图中我是为了方便学习特意添加注释,当控件写完后可将注释去掉即可
《学习笔记》Layui-WPF窗体美化的更多相关文章
- 【HLSL学习笔记】WPF Shader Effect Library算法解读之[DirectionalBlur]
原文:[HLSL学习笔记]WPF Shader Effect Library算法解读之[DirectionalBlur] 方位模糊是一个按照指定角度循环位移并叠加纹理,最后平均颜色值并输出的一种特效. ...
- 【HLSL学习笔记】WPF Shader Effect Library算法解读之[Embossed]
原文:[HLSL学习笔记]WPF Shader Effect Library算法解读之[Embossed] Embossed(浮雕效果) 浮雕效果主要有两个参数:Amount和Wid ...
- 【HLSL学习笔记】WPF Shader Effect Library算法解读之[BandedSwirl]
原文:[HLSL学习笔记]WPF Shader Effect Library算法解读之[BandedSwirl] 因工作原因,需要在Silverlight中使用Pixel Shader技术,这对于我来 ...
- PyQt5学习笔记-从主窗体打开一个子窗体
PyQt5学习笔记-从主窗体打开一个子窗体 软件环境: Eric6+Python3.5+PyQt5 试验目标: 1.点击菜单项Open,打开一个子窗体 2.点击按钮Open,打开一个子窗体 主窗体设计 ...
- WPF 学习笔记-在WPF下创建托盘图标
原文:WPF 学习笔记-在WPF下创建托盘图标 首先需要在项目中引用System.Windows.Forms,System.Drawing; using System; using System.Co ...
- WPF学习笔记(8):DataGrid单元格数字为空时避免验证问题的解决
原文:WPF学习笔记(8):DataGrid单元格数字为空时避免验证问题的解决 如下图,在凭证编辑窗体中,有的单元格不需要数字,但如果录入数字后再删除,会触发数字验证,单元格显示红色框线,导致不能执行 ...
- WPF的学习笔记(1) -- (积累自2016年5月1日 至 2016年6月1日)
敬告读者:因为是事件驱动模式的高速学习,高速学习意味着,不系统,不科学,不合逻辑,不一定正确.所以要是有不对的地方,页面下面留言给我,跪谢! 背景介绍: 最近在公司的开发工作中,接手了从别的公司交代过 ...
- WPF的Binding学习笔记(二)
原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...
- Duilib学习笔记《06》— 窗体基类WindowImpBase
在前面的例子中我们发现,窗口都是继承CWindowWnd.INotifyUI,然后重载相关函数去实现.显然,我们发现窗口的创建流程实际上都是差不多的,主要只是在OnCreate加载的配置文件不同等等… ...
随机推荐
- Java面试系列第2篇-Object类中的方法
Java的Object是所有引用类型的父类,定义的方法按照用途可以分为以下几种: (1)构造函数 (2)hashCode() 和 equals() 函数用来判断对象是否相同 (3)wait().wai ...
- pytorch Dataset数据集和Dataloader迭代数据集
import torch from torch.utils.data import Dataset,DataLoader class SmsDataset(Dataset): def __init__ ...
- 重大更新!Druid 0.18.0 发布—Join登场,支持Java11
Apache Druid本质就是一个分布式支持实时数据分析的数据存储系统. 能够快速的实现查询与数据分析,高可用,高扩展能力. 距离上一次更新刚过了二十多天,距离0.17版本刚过了三个多月,Druid ...
- 【Linux常见命令】dos2unix命令,unix2dos命令
我们都知道.打回车键就是换行的意思. 在不同系统下打回车键效果是不同的: MAC OS下:dakdhih \r LINUX下:dakdhih \n DOS\WINDOWS下:dakdhih \r\n ...
- 爱创课堂每日一题第十五题HTTP和HTTPS?
HTTP协议通常承载于TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS.默认HTTP的端口号为80,HTTPS的端口号为443. 转载于 ...
- 负载均衡服务之HAProxy https配置、四层负载均衡以及访问控制
前文我们聊了下haproxy的访问控制ACL的配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12817773.html:今天我们来聊一聊haproxy的h ...
- vue中给window添加滚动监听无效的解决方案
原文链接: 点我 页面中有这么一个需求,当页面滚动到一定高度之后,页面中的某些元素进行吸顶,固定到顶部位置,或者是滚动到一定程度进行更新数据的操作.我相信不少网友查阅过类似的资料,网友给出的解决方案, ...
- POJ 1905 Expanding Rods(二分)
Expanding Rods Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 20224 Accepted: 5412 Descr ...
- Android JetPack组件-CameraX初探
CameraX 又是一个 Google 推出的 JetPack 组件 ,是一个新鲜玩意儿,故给大家分享下我在项目中的使用过程心得.. CameraX 是什么? Google 开发者文档 对 Camer ...
- 【Java8新特性】你知道Java8为什么要引入Lambda表达式吗?
写在前面 这是一道真实的面试题,一个读者朋友出去面试,面试官竟然问他这样一个问题:你说说Java8中为什么引入Lambda表达式?引入Lambda表达式后有哪些好处呢?还好这个朋友对Java8早有准备 ...