一个较好的style与ControlTemplate结合的示例(以Button为例)

    <!--按钮背景画刷-->
    <LinearGradientBrush x:Key="buttonBackgroundBrush">
        <GradientStop Offset="0" Color="Beige"/>
        <GradientStop Offset="1" Color="White"/>
    </LinearGradientBrush>    
    <Sys:String x:Key="bgImg">"..\images\bgImg.png"</Sys:String>

    <Color x:Key="bgColorBlack">Black</Color>


    <!--按钮模板定义,说明:控件模板不但可以通过拆解控件,并修改可视化元素树来完成;也可以“根据自我想象”,任意地自定义,只要达到需求的效果就好,但这样,程序员可能要写大量的触发器、样式等等,这些效果可以参照“拆解控件”时生成的xaml代码-->
    <ControlTemplate x:Key="TestButtonTemplate" TargetType="{x:Type Button}">
        <Border x:Name="border" BorderThickness="1" BorderBrush="Black"
                      Background="{StaticResource buttonBackgroundBrush}"
                      CornerRadius="10">
            <Grid>
                <Image x:Name="image" Source="a.png"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            Stretch="Fill" Height="50" Width="50"/>
                <Label Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"/>  <!--由于该自定义模板破坏掉button控件原有的很多效果和功能(如:Button控件的Content属性值的外在显示),所以这里使用<Label Content来展示<Button Content的属性值,我们在外部依然是给button按钮的content属性赋值,而这个值在Lable的Content属性值中展示出来,故需要通过“Binding RelativeSource”来获得我们在控件外部输入的Button Content属性值。
            </Grid>
        </Border>
       
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="true"><!--针对Button的-->
                <Setter TargetName="image" Property="Source" Value="b.png"/><!--但它针对Button的组成元素之一:“images”,而不针对其它的组成元素-->
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate> <!--数据模板是描述“数据项”风格的一种模板,数据集合中所有数据记录的风格都是一致的;控件模板是针对控件的外在显示,而与数据是无关的;数据模板是针对数据项的、控件模板是针对控件的;数据模板是渲染控件中的数据的、控件模板是渲染控件自身的,不包括数据-->
    
    <!--按钮样式定义,实际只需要在Button的Style中引用这个就好-->
    <Style x:Key="TestButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="FontSize" Value="15"/>
        <Setter Property="FontWeight" Value="bold"/>
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="Foreground" Value="Blue"/>
        <Setter Property="Template" Value="{StaticResource TestButtonTemplate}"/><!--good-->
    </Style>

 

说明:上例中的Style、ControlTemplate、LinearGradientBrush等元素,都属于“资源”(而不是控件),所以通常放在资源区域 或 资源字典 中。可以把用户控件和window整体分为“资源区域”和“布局区域”,资源区域存放各种资源(如:style,controltemplate、datatemplate、string、brush等,并且资源的标识是x:key);布局区域存放各种控件(如:grid,button,textbox等等,并且控件的标识是x:name),需要注意的是,许多控件自身也有resouce。

 

WPF重要知识回顾:

 Style、ControlTemplate、DataTemplate三者可以并列,后两者也可以嵌入到Style当中;另外,这三者都可以有“自己的”触发器

依赖属性(通常被控件拥有,它可以Binding到ViewModel的属性上),路由事件(可导致对应的“事件触发器”被触发)

触发器:属性,数据,事件(路由事件的激发 会 导致 事件触发器 被激发,事件触发器中,通常使用动画处理),使用触发器的意义:主要是为了产生“界面效果”。补充:Style、ControlTemplate、DataTemplate 和 UIElement都有Triggers

动画:经常使用Storybord来实现动画效果

综上所述:以上这些知识都是为了产生界面效果的,所以WPF的核心就是为了渲染界面效果的。

posted @   长白山  阅读(577)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
历史上的今天:
2013-09-06 Arcgis 中国区技术支持 官网
2013-09-06 【转】ArcGIS API for Silverlight/WPF 2.1学习笔记(四)
2013-09-06 【转】ArcGIS API for Silverlight/WPF 2.1学习笔记(五)
2013-09-06 【转】ArcGIS API for Silverlight/WPF 2.1学习笔记(三)
2013-09-06 【转】ArcGIS API for Silverlight/WPF 2.1学习笔记(二)
2013-09-06 【转】ArcGIS API for Silverlight/WPF 2.1学习笔记(一)
2013-09-06 在WinForm应用程序中嵌入WPF控件
点击右上角即可分享
微信分享提示