前言:Button算是开发中用到的比较多的控件了,最开始使用原生的样式,长方形的样子,然后设置下Button的Content属性。随着学习的深入,需要去设置下Button的背景色,再往后就需要改下Button的模板来满足更高的需求设计。

一、简介

可以看到,Button继承至ContentControl控件, Button有个Content属性而这个Content可以是多种控件形式,查看Button的模板可以看到,用来承载这个内容的是一个ContentPresenter控件。

通过官网可以看到这个ContentPresenter类的继承关系

二、Background

简单的如下

<Button Background="AliceBlue"/>

可以看到,这个Background属性类型是Brush,因此我们可以通过应用不同的Brush来改变Button的Background,从而使Background更加丰富。

官网中对Brush的注解,Brush有多个继承者,都可以用

2.1  LinearGradientBrush

<Button Width="60" Height="60"><Button.Background><LinearGradientBrush EndPoint="0.851,0.838" StartPoint="0.115,0.169"><GradientStop Color="#FFA21212" Offset="0"/><GradientStop Color="#FFF8C906" Offset="1"/></LinearGradientBrush></Button.Background>
</Button>

2.2 RadialGradientBrush

<Button Width="60" Height="60"><Button.Background><RadialGradientBrush><GradientStop Color="#FFA21212" Offset="1"/><GradientStop Color="#FFF8C906" Offset="0"/></RadialGradientBrush></Button.Background>
</Button>

2.3 ImageBrush 

            <Button Width="60" Height="60"><Button.Background><ImageBrush ImageSource="/项目.png"/></Button.Background></Button>

2.4 DrawingBrush 

            <Button Width="60" Height="60"><Button.Background><DrawingBrush Viewport="0,0,0.5,0.5" TileMode="Tile"><DrawingBrush.Drawing><GeometryDrawing Brush="Red"><GeometryDrawing.Geometry><GeometryGroup><EllipseGeometry RadiusX="20" RadiusY="45" Center="50,50" /><EllipseGeometry RadiusX="45" RadiusY="20" Center="50,50" /></GeometryGroup></GeometryDrawing.Geometry><GeometryDrawing.Pen><Pen Thickness="10"><Pen.Brush><LinearGradientBrush><GradientStop Offset="0.0" Color="Black" /><GradientStop Offset="1.0" Color="Gray" /></LinearGradientBrush></Pen.Brush></Pen></GeometryDrawing.Pen></GeometryDrawing></DrawingBrush.Drawing></DrawingBrush></Button.Background></Button>

2.5 VisualBrush

            <Button Width="60" Height="60"><Button.Background><VisualBrush><VisualBrush.Visual><StackPanel Background="White"><Rectangle Width="25" Height="25" Fill="Orange" Margin="6" /><TextBlock FontSize="10pt" Margin="2">BrawDraw</TextBlock><Button Margin="10">Button</Button></StackPanel></VisualBrush.Visual></VisualBrush></Button.Background></Button>

二、Content

2.1 字符串

<!--Create a Button with a string as its content.-->
<Button Content="1111111111" Height="60" Width="60"/>
<Button>This is string content of a Button</Button>

2.2  DateTime object

<!--Create a Button with a DateTime object as its content.-->
<Button xmlns:sys="clr-namespace:System;assembly=mscorlib"><sys:DateTime>2004/3/4 13:6:55</sys:DateTime>
</Button>

2.3 UIElement

<!--Create a Button with a single UIElement as its content.-->
<Button><Rectangle Height="40" Width="40" Fill="Blue"/>
</Button>

2.4 panel

<!--Create a Button with a panel that contains multiple objects
as its content.-->
<Button><StackPanel><Ellipse Height="40" Width="40" Fill="Blue"/><TextBlock TextAlignment="Center">Button</TextBlock></StackPanel>
</Button>

2.5 说明

Because the Content property is of type Object, there are no restrictions on what you can put in a ContentControl. The Content is displayed by a ContentPresenter, which is in the ControlTemplate of the ContentControl. Every ContentControl type in WPF has a ContentPresenter in its default ControlTemplate.

由于Content属性的类型是Object,因此对可以放入的内容ContentControl没有限制。该Content属性通过ContentPresenter显示,而这个ContentPresenter存在于ContentControl的ControlTemplate属性中。WPF中的每一个ContentControl类型控件都有一个ContentPresenter属性,默认存在ControlTemplate中。

三、外观

The ContentPresenter uses the following logic to display the Content (ContentPresenter就是用来显示Content的,下面是显示逻辑):

  • If the ContentTemplate property on the ContentPresenter is set, the ContentPresenter applies that DataTemplate to the Content property and the resulting UIElement and its child elements, if any, are displayed. For more information about DataTemplate objects, see Data Templating Overview.(如果ContentTemplate设置了ContentPresenter属性,那么ContentPresenter就应用DataTemplate作为Content属性和UIElement及其子元素的结果。)

  • If the ContentTemplateSelector property on the ContentPresenter is set, the ContentPresenter applies the appropriate DataTemplate to the Content property and the resulting UIElement and its child elements, if any, are displayed.(和上一个差不多,就是把ContentTemplate换成了ContentTemplateSelector)

  • If there is a DataTemplate associated with the type of Content, the ContentPresenterapplies that DataTemplate to the Content property and the resulting UIElement and its child elements, if any, are displayed.(如果有DataTemplate与类型Content相关联的类型,则ContentPresenter就用DataTemplate作为其Content)

  • If Content is a UIElement object, the UIElement is displayed. If the UIElement already has a parent, an exception occurs.(如果Content是一个UIElement对象,就显示这个UIElement对象)

  • If there is a TypeConverter that converts the type of Content to a UIElement, the ContentPresenter uses that TypeConverter and the resulting UIElement is displayed.(转换器的应用,Content和UIElement转换)

  • If there is a TypeConverter that converts the type of Content to a string, the ContentPresenter uses that TypeConverter and creates a TextBlock to contain that string. The TextBlock is displayed.(转换器的应用,Content和string转换,并创建一个TextBlock控件去承载这个sting)

  • If the content is an XmlElement, the value of the InnerText property is displayed in a TextBlock.(Content是XmlElement)

  • The ContentPresenter calls the ToString method on the Content and creates a TextBlock to contain the string returned by ToString. The TextBlock is displayed.(ContentPresenter会在Content上调用Tosting方法并创建一个TextBlock去承载这个string)

3.1 原生样式

        <Style x:Key="ButtonStyle2" TargetType="{x:Type Button}"><Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual1}"/><Setter Property="Background" Value="{StaticResource Button.Static.Background1}"/><Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border1}"/><Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/><Setter Property="BorderThickness" Value="1"/><Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="Padding" Value="1"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Button}"><Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true"><ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Border><ControlTemplate.Triggers><Trigger Property="IsDefaulted" Value="true"><Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/></Trigger><Trigger Property="IsMouseOver" Value="true"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background1}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border1}"/></Trigger><Trigger Property="IsPressed" Value="true"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background1}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border1}"/></Trigger><Trigger Property="IsEnabled" Value="false"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background1}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border1}"/><Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground1}"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>

有关外观的设计就在ControlTemplate属性上,这个原生的没做什么改变,如果设置Content为string,就会像上面最后一条一样,Content调用ToString去转换并创建个TextBlock去承载这个转换后的string。

3.2 UIElement

使用image作为Content的元素,上面第四条所说的。

<Button Height="60" Width="60"><Image Source="/项目.png"/>
</Button>

3.2 修改ControlTemplate

原生的样式,边框很明显,这时就需要修改下ControlTemplate了

<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}"><Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/><Setter Property="Background" Value="{StaticResource Button.Static.Background}"/><Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/><Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/><Setter Property="BorderThickness" Value="1"/><Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="Padding" Value="1"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type Button}"><Grid><Grid.RowDefinitions><RowDefinition Height="0"/><RowDefinition Height="*"/></Grid.RowDefinitions><Image Source="/Resource/send.png" Margin="0 10 0 0"/><Border x:Name="border"  BorderThickness="1" SnapsToDevicePixels="true" Grid.Row="1"><ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Border></Grid><ControlTemplate.Triggers><Trigger Property="IsDefaulted" Value="true"><Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/></Trigger><Trigger Property="IsMouseOver" Value="true"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/></Trigger><Trigger Property="IsPressed" Value="true"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/></Trigger><Trigger Property="IsEnabled" Value="false"><Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/><Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/><Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>

我们把ControlTemplate摘出来看看,原样式中使用一个Border包裹一个ContentPrensenter。

修改后使用了Grid作为ContentPresenter的父容器。其实这里分了两层,一层高度是0,其实就一层。

这里还有个问题,就是鼠标移动上去后,会有个背景,不好看

这个背景是在 ControlTemplate.Triggers中设置的,设置的属性是IsMouseOver。想去掉这个背景,暴力点的做法直接注释掉那段代码。

3.3 升级

鼠标移上去会放大这个Content,笔者代码中Content设置为Image类型的。

        <Style x:Key="ButtonStyle" TargetType="{x:Type Button}"><Setter Property="VerticalAlignment" Value="Center"/><Setter Property="HorizontalAlignment" Value="Center"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="Template"><Setter.Value><ControlTemplate  TargetType="{x:Type Button}"><ControlTemplate.Resources><Storyboard x:Key="Storyboard1"><DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="grid"><SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="1.25"/></DoubleAnimationUsingKeyFrames><DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="grid"><SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="1.25"/></DoubleAnimationUsingKeyFrames></Storyboard><Storyboard x:Key="Storyboard2"><DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="grid"><SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/></DoubleAnimationUsingKeyFrames><DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="grid"><SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/></DoubleAnimationUsingKeyFrames></Storyboard></ControlTemplate.Resources><Grid x:Name="grid" RenderTransformOrigin="0.5,0.5"><Grid.RenderTransform><TransformGroup><ScaleTransform/><SkewTransform/><RotateTransform/><TranslateTransform/></TransformGroup></Grid.RenderTransform><Label Name="lbl" Content="{TemplateBinding Content}" Background="Transparent" Height="{TemplateBinding Height}"Width="{TemplateBinding Width}" VerticalAlignment="Center" HorizontalAlignment="Center"/></Grid><ControlTemplate.Triggers><Trigger Property="IsFocused" Value="True"/><Trigger Property="IsDefaulted" Value="True"/><Trigger Property="IsMouseOver" Value="True"><!--<Setter Property="Background" TargetName="lbl" Value="red"/>--><Trigger.ExitActions><BeginStoryboard x:Name="Storyboard_Copy1_BeginStoryboard" Storyboard="{StaticResource Storyboard2}"/></Trigger.ExitActions><Trigger.EnterActions><BeginStoryboard Storyboard="{StaticResource Storyboard1}"/></Trigger.EnterActions></Trigger><Trigger Property="IsPressed" Value="True"><Setter Property="Background" TargetName="lbl" Value="#000000FF"/></Trigger><Trigger Property="IsEnabled" Value="False"/></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style>

加了个动画,然后在 IsMouseOver事件中进行操作。

四、引用文献

4.1 Button 类 (System.Windows.Controls) | Microsoft Docs

4.2 ContentPresenter 类 (System.Windows.Controls) | Microsoft Docs

4.3 Brush 类 (System.Windows.Media) | Microsoft Docs

4.4 简述WPF中的画刷(Brush)_Andrewniu的博客-CSDN博客_brush wpf

4.5 ContentControl.Content 属性 (System.Windows.Controls) | Microsoft Docs

15、wpf之button样式小记相关推荐

  1. WPF XAML 资源样式模板属性存放位置

    WPF XAML 资源样式模板属性存放位置 原文:WPF XAML 资源样式模板属性存放位置 WPF的XAML 资源申明 类似HTML. 整体来说分3种 1.行类资源样式属性 1.1 行内属性 < ...

  2. 【转】WPF自定义控件与样式(3)-TextBox RichTextBox PasswordBox样式、水印、Label标签、功能扩展...

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要是对文本输入控件进行样式开发,及相关扩展功能开发,主要内容包括: 基本文 ...

  3. WPF快速入门系列(6)——WPF资源和样式

    WPF快速入门系列(6)--WPF资源和样式 一.引言 WPF资源系统可以用来保存一些公有对象和样式,从而实现重用这些对象和样式的作用.而WPF样式是重用元素的格式的重要手段,可以理解样式就如CSS一 ...

  4. WPF自定义控件与样式(1)-矢量字体图标(iconfont)

    原文:WPF自定义控件与样式(1)-矢量字体图标(iconfont) 一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序 ...

  5. WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

    原文:WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展 一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐 ...

  6. WPF编程学习 —— 样式

    本文目录 1.引言 2.怎样使用样式? 3.内联样式 4.已命名样式 5.元素类型样式 6.编程控制样式 7.触发器 1.引言 样式(Style),主要是用来让元素或内容呈现一定外观的属性.WPF中的 ...

  7. WPF 控件样式及样式事件设置

    实例下载:WPF控件样式及样式事件设置-C#文档类资源-CSDN下载 封装用户控件实例:图片选择Checkbox(用户控件)-C#文档类资源-CSDN下载 1.直接在代码中设置控件样式(例:设置按键圆 ...

  8. WPF控件样式、模板

    初次写博客,新手请多指教. 写WPF已有一年有余了,平时在工作项目当中喜欢总结一些公用库,通用样式之类的,以便于日后工作中遇到,可以直接复用,提供工作效率. 本文提供 Windows.Button.S ...

  9. Android移动开发之【Android实战项目】漂亮Button样式

    开发中各种样式的Button,其实这些样式所有的View都可以共用的,可能对于你改变的只有颜色 所有的都是用代码实现 文章目录 边框样式,给你的View加上边框 圆角Button 带点击状态的Butt ...

最新文章

  1. [Mongodb]删除指定字段
  2. jquery validate 插件:(2)简单示例
  3. 蓝牙模块与电脑无线通信--AD测量大电压
  4. uniapp动态显示数组_uni-app学习:4、数据绑定(变量、数组、显示控制)
  5. 【深度学习】Panoptic FCN:真正End-to-End的全景分割
  6. [html] 如何解决微信浏览器视频点击自动全屏的问题?
  7. qt如和调用linux底层驱动_擅长复杂硬件体系设计,多核系统设计,以及基于RTOS或者Linux,QT等进行相关底层驱动。...
  8. Rstudio更换主题/样式
  9. 全面解析腾讯最新开源 loT 操作系统 TencentOS tiny!
  10. FR跨SHEET条件汇总
  11. 重装驱动:Failed to initialize NVML: Driver/library version mismatch
  12. 2017美赛A题论文阅读笔记
  13. 《免费:商业的未来》“免费经济学”读书笔记----字节跳动案例分析
  14. 下载阿里云大学的课程
  15. activity多实例任务节点审批
  16. Day54.XML解析(DOM4J)、Tomcat服务器、HTML协议简介: 请求、响应报文、响应码
  17. 使用C语言构造一个简单计算器
  18. android pc扩展屏幕分辨率,让闲置的iPad / Android平板电脑成为计算机屏幕的扩展显示!...
  19. matlab报错问题处理,函数或变量无法识别,不受支持的符号、不可见的字符或非 ASCII 字符的粘贴———卸载之前
  20. 3-2-1 程序控制结构-while循环结构-多次求解一元二次方程?-while循环常见错误?

热门文章

  1. Android WebView的WebSettings常用方法介绍,聊聊 Android 开发的现状和思考
  2. Hi3516D 数据手册
  3. 深入解读 Seata 的 XA 模式
  4. C++获取当前时间 (std::chrono)
  5. 用DM对硬盘分区过程详解
  6. java继承(implements与extends)总结
  7. JAVA学习之:implements的用法
  8. Double和double的区别
  9. 关于用户头像上传的配置
  10. ubuntu20.04界面黑屏,有光标闪烁,解决方法