《学习笔记》Layui-WPF窗体美化

时间:2021-11-07 07:43:42

一睹为快:

《学习笔记》Layui-WPF窗体美化

1.创建自定义控件,并取名为LayuiWPFStyle

《学习笔记》Layui-WPF窗体美化

《学习笔记》Layui-WPF窗体美化

2.在当前目录中创建Fonts和WindowStyle文件加用来存放字体文件和自定义窗体,字体用fontawesome字体当然你们可以用自己的自己也行

《学习笔记》Layui-WPF窗体美化

3.创建自定义控件,并取名为LayWindow,记住是WPF的别点错了

《学习笔记》Layui-WPF窗体美化

《学习笔记》Layui-WPF窗体美化

4.双击LayWindow让当前类文件继承Window

《学习笔记》Layui-WPF窗体美化

5.由于我们窗体分为头部和内容,而头部分为窗体名称和窗体图标以及窗体按钮组成

《学习笔记》Layui-WPF窗体美化

6.此时我们需要对窗体进行重绘以及添加必要的附加属性,快捷键Propdp+双击Tab,MyProperty是扩展属性名称我们可以随便定义,例如我们需要定义窗体头部栏高度我们可以定义为HearderHieght,类型为Int,ownerclass替换为当前自定义窗体的名称:LayWindow,

如图二

《学习笔记》Layui-WPF窗体美化

《学习笔记》Layui-WPF窗体美化

7.进入Generic.xaml文件中,我们会发现当我们每创建一个自定义控件时系统会默认帮我创建一个简单的Style样式,但是此时的样式时不奏效的,他只是给我们个友好的提示。此时我们需要开始从写窗体样式了,我们可以将窗体分为两份,一份为头部一分为身体(也就是内容)我们可以使用RowDefinitions进行分行,头部高度设置为自适应类容高度如图Height="auto"

《学习笔记》Layui-WPF窗体美化

8.创建一个头部栏:并且此时可以开始用上我们的自定义属性HearderHieght,切记我们自定义的属性想要生效不能用TemplateBinding(模板绑定)进行绑定必须要用Binding(数据源绑定)进行绑定如:Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}"

《学习笔记》Layui-WPF窗体美化

9.窗体内容我们用ContentPresenter进行组合使用

《学习笔记》Layui-WPF窗体美化

10.定制窗体头部,分别头部分为三列,左边分为窗体图标和窗体名称,中间预留,右边分为最大化、最小化和关闭按钮,为了方便我们统一颜色我将背景色单独抽离开

《学习笔记》Layui-WPF窗体美化

《学习笔记》Layui-WPF窗体美化

   <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,并且引用我们刚刚做好的窗体

《学习笔记》Layui-WPF窗体美化

13.窗机WPF项目中的App.xaml文件添加自定义控件的相关样式文件

《学习笔记》Layui-WPF窗体美化

 <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"如图

《学习笔记》Layui-WPF窗体美化

《学习笔记》Layui-WPF窗体美化

16.按F7进入后台代码让MainWindow继承我们的LayWindow

《学习笔记》Layui-WPF窗体美化

《学习笔记》Layui-WPF窗体美化

17.此时我们的自定义窗体就完成啦,点击运行就得到我们的美化后的窗体(顶部左侧的Ico图标可忽略自己也可以添加一个Ico图标)

《学习笔记》Layui-WPF窗体美化

注意:如若你的项目运行出错很有可能你的Generic.xaml文件里面有文字注释,上图中我是为了方便学习特意添加注释,当控件写完后可将注释去掉即可

《学习笔记》Layui-WPF窗体美化的更多相关文章

  1. 【HLSL学习笔记】WPF Shader Effect Library算法解读之&lbrack;DirectionalBlur&rsqb;

    原文:[HLSL学习笔记]WPF Shader Effect Library算法解读之[DirectionalBlur] 方位模糊是一个按照指定角度循环位移并叠加纹理,最后平均颜色值并输出的一种特效. ...

  2. 【HLSL学习笔记】WPF Shader Effect Library算法解读之&lbrack;Embossed&rsqb;

    原文:[HLSL学习笔记]WPF Shader Effect Library算法解读之[Embossed] Embossed(浮雕效果)          浮雕效果主要有两个参数:Amount和Wid ...

  3. 【HLSL学习笔记】WPF Shader Effect Library算法解读之&lbrack;BandedSwirl&rsqb;

    原文:[HLSL学习笔记]WPF Shader Effect Library算法解读之[BandedSwirl] 因工作原因,需要在Silverlight中使用Pixel Shader技术,这对于我来 ...

  4. PyQt5学习笔记-从主窗体打开一个子窗体

    PyQt5学习笔记-从主窗体打开一个子窗体 软件环境: Eric6+Python3.5+PyQt5 试验目标: 1.点击菜单项Open,打开一个子窗体 2.点击按钮Open,打开一个子窗体 主窗体设计 ...

  5. WPF 学习笔记-在WPF下创建托盘图标

    原文:WPF 学习笔记-在WPF下创建托盘图标 首先需要在项目中引用System.Windows.Forms,System.Drawing; using System; using System.Co ...

  6. WPF学习笔记(8):DataGrid单元格数字为空时避免验证问题的解决

    原文:WPF学习笔记(8):DataGrid单元格数字为空时避免验证问题的解决 如下图,在凭证编辑窗体中,有的单元格不需要数字,但如果录入数字后再删除,会触发数字验证,单元格显示红色框线,导致不能执行 ...

  7. WPF的学习笔记&lpar;1&rpar; -- (积累自2016年5月1日 至 2016年6月1日)

    敬告读者:因为是事件驱动模式的高速学习,高速学习意味着,不系统,不科学,不合逻辑,不一定正确.所以要是有不对的地方,页面下面留言给我,跪谢! 背景介绍: 最近在公司的开发工作中,接手了从别的公司交代过 ...

  8. WPF的Binding学习笔记&lpar;二&rpar;

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  9. Duilib学习笔记《06》— 窗体基类WindowImpBase

    在前面的例子中我们发现,窗口都是继承CWindowWnd.INotifyUI,然后重载相关函数去实现.显然,我们发现窗口的创建流程实际上都是差不多的,主要只是在OnCreate加载的配置文件不同等等… ...

随机推荐

  1. PS技巧:如何优雅的抠公章?

    搞设计的很苦逼,整天面对各种各样任务,除了修图.排版外,还时不时会有些另类需求.这时如果掌握一些小技巧就不用临时抱佛脚啦. 下面献上一计:教大家怎么用PS抠公章.有需要的拿去,PS:不要干坏事吆! 效 ...

  2. Sublime Text2 Jsformat自定义使用之代码折叠方式修改

    将代码括号的折叠方式从 function abc(){ } 变成 function abc() { } 打开 Setting-user,把setting-default里的文本全部复制过来. 然后 将 ...

  3. OpenJudge计算概论-校门外的树

    /*======================================================================== 校门外的树 总时间限制: 1000ms 内存限制: ...

  4. I want to try to improve myself from today

    I involved in the Internet of Things project team in my university in 2015 and now I have completed ...

  5. poj1222 高斯消元

    给了一个01矩阵然后选在一个点1变0或者0变1 然后 与他相邻的 数也相应的变成相反的数,问最后求出一种方案把他们变成全0 将每一个位置上的状态看做一个变元,30个变元,列出30个异或方程 #incl ...

  6. win10 下 配置php环境变量

    注意,只需要配置到目录即可:

  7. Netty 零拷贝(三)Netty 对零拷贝的改进

    Netty 零拷贝(三)Netty 对零拷贝的改进 Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html) Netty 的&quo ...

  8. iOS边练边学--view的封装

    一.view封装的思路: *如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部的子控件的创建屏蔽起来,不让外界关心 *外界可以传入对应的模型数据给view,view拿到模型数据 ...

  9. bootstrap class sr-only 什么意思?

    bootstrap class sr-only 什么意思? 在看 bootstrap 内联表单时,label 有一个 class 是 sr-only. sr-only 是给屏幕阅读器用的,是给视力不方 ...

  10. (剑指Offer)面试题39:判断平衡二叉树

    题目: 输入一课二叉树的根结点,判断该树是不是平衡二叉树.如果二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树. 思路: 1.重复遍历结点 参考上一题求二叉树的深度,先求出根结点 ...