深入浅出WPF-11.Template(模板)01
模板
在WPF中,模板可以分为两大类:
控件模板(ControlTemplate)是算法内容的表现形式,一个控件怎么组织其内部的结构才能让它更符合业务逻辑,让用户操作更舒服,都是由她控制的。它决定了控件长什么样子,并让程序员有机会在控件原有的内部逻辑基础上扩展自己的逻辑。
数据模板(DataTemplate)是数据内容的表现形式,一条数据表现成什么样子,是简单的文本还是直观的图形动画就由他决定。
我们先了解一下数据模板,同样一条数据比如拥有类Student实例,具有如下就一个字段:
public class Student
{
/// <summary>
/// 索引
/// </summary>
public int Id { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 性别
/// </summary>
public Sex Sex { get; set; }
/// <summary>
/// 出生日期
/// </summary>
public DateTime BirthDate { get; set; }
}
/// <summary>
/// 性别
/// </summary>
public enum Sex : byte
{
/// <summary>
/// 男
/// </summary>
Male = 0,
/// <summary>
/// 女
/// </summary>
Female = 1,
/// <summary>
/// 其他
/// </summary>
Other = 2,
}
这样的内容,在不同的控件中展示,展示的形式会不一样,这种模式称之为 数据-视图 模式。在WPF中,我们可以使用自定义控件UserControl来实现,也可以使用数据模板DataTemplate实现。
DataTemplate常用在下面情况下:
- ContentControl的ContentTemplate属性,相当与给ContentControl的内容穿衣服
- ItemsControl 的ItemTemplate属性,相当远给ItemsControl的数据条目穿衣服
- GridViewColumn的CellTemplate属性,相当于给GridViewColumn的单元格的数据穿衣服
我么你先看一下一个程序的展示效果
这里我们看一下代码实现:
<UserControl
x:Class="LpbPrj.Client.Views.ResultWideAreaImagingView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:LpbPrj.Client.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:langs="clr-namespace:LpbPrj.Client.Properties.Langs"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/">
<ListBox
Margin="0,0,0,0"
control:CustomeSelectionItems.SelectedItems="{Binding ResultSelectedItems}"
BorderThickness="0"
ItemsPanel="{StaticResource FluidMoveBehaviorWrapPanelItemsPanelTemplate}"
ItemsSource="{Binding ResultList}"
SelectedItem="{Binding Result}"
SelectionMode="{Binding SelectionMode}"
Style="{StaticResource WrapPanelHorizontalListBox}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<ContentControl prism:RegionManager.RegionName="ItemWideAreaImaging" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</UserControl>
在这个ListBox中,我们对其中的ItemTemplate穿衣服,这个衣服的内容是:
<UserControl
x:Class="LpbPrj.Client.Views.ItemWideAreaImaging"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:langs="clr-namespace:LpbPrj.Client.Properties.Langs"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/">
<hc:Card
MaxWidth="240"
Margin="8"
BorderThickness="0"
Effect="{StaticResource EffectShadow2}"
Footer="{Binding}"
Header="{Binding}">
<hc:Card.HeaderTemplate>
<DataTemplate>
<TextBlock
Margin="5"
Style="{StaticResource TextBlockDefault}"
Text="{Binding ExamType, Converter={StaticResource DtoShowStringConverter}}" />
</DataTemplate>
</hc:Card.HeaderTemplate>
<Border CornerRadius="4,4,0,0" Style="{StaticResource BorderClip}">
<Grid>
<Image Source="{Binding ImageThumbPath, Converter={StaticResource Path2BitmapImageConverter}}" Stretch="Uniform" />
</Grid>
</Border>
<hc:Card.FooterTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0"
Margin="5"
Orientation="Horizontal">
<TextBlock
Style="{StaticResource TextBlockDefault}"
Text="{Binding ExamFileType, Converter={StaticResource DtoShowStringConverter}}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
<TextBlock
Margin="10,0,0,0"
Style="{StaticResource TextBlockDefault}"
Text="{Binding ExamImageType, Converter={StaticResource ExamImageTypeConverter}}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
<TextBlock
Margin="10,0,0,0"
Style="{StaticResource TextBlockDefault}"
Text="{Binding EyeType, Converter={StaticResource DtoShowStringConverter}}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
</StackPanel>
<CheckBox
Grid.Column="1"
Width="30"
Height="30"
Margin="10,0,5,0"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
</Grid>
</DataTemplate>
</hc:Card.FooterTemplate>
</hc:Card>
</UserControl>
这段代码中的prism,我们暂且不管,但是主要内容还是能够理解的,我们使用了一个Card控件进行描述ListBox的展示内容,每个Card又通过TextBlock和CheckBox等控件进行描述。TextBlock中的对应的数据类型可能不能直接用于展示,比如枚举值,时间类型等。这里我们通过转化Converter来实现想要的展示形式。
这里面存在一个认识的误区,在上面的代码中,我们认为ListBox的Items属性里面存放的是数据而不是控件。我们可以直接将ListBox的选中属性SelectedItem绑定到一个对应的数据实例中。这种模式叫做数据驱动模式。和我们之前使用的事件驱动模式不一样。事件驱动是控件和控件之间沟通或者说是形式和形式之间的沟通,而数据驱动则是数据与控件之间的沟通,是内容和形式之间的沟通。
数据模板理解之后,我们再看一下控件模板ControlTemplate,我们可以使用披着羊皮的狼来理解控件模板,表面上看上去是羊,但是其实是狼。所以控件模板只是改变了控件的外形,不能改变控件的本质。对应控件外形的编辑我们推荐使用Blend。
我们先看一个简单的Lable标签:
<Style x:Key="LabelBaseStyle" TargetType="{x:Type Label}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.4" />
</Trigger>
</Style.Triggers>
<Setter Property="Foreground" Value="{DynamicResource TextIconBrush}" />
<Setter Property="Background" Value="{DynamicResource RegionBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}" />
<Setter Property="CornerRadius" Value="{StaticResource DefaultCornerRadius}" />
<Setter Property="Padding" Value="{StaticResource DefaultControlPadding}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我们对Lable标签的ControlTemplate进行修改,里面包含了一个控件Border,Border内部包含了控件的内容ContentPresenter。Border的属性通过绑定设置了BorderBrush="{TemplateBinding BorderBrush}" ,代表Border的BorderBrush属性需要绑定到Label的BorderBrush属性,两者保持一致。
深入浅出WPF-11.Template(模板)01的更多相关文章
- 《深入浅出WPF》笔记——模板篇
原文:<深入浅出WPF>笔记--模板篇 我们通常说的模板是用来参照的,同样在WPF中,模板是用来作为制作控件的参照. 一.认识模板 1.1WPF菜鸟看模板 前面的记录有提过,控件主要是算法 ...
- c++11 template 模板练习
直接上代码吧 to do // 111111.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> ...
- 《深入浅出WPF》笔记——资源篇
原文:<深入浅出WPF>笔记--资源篇 前面的记录有的地方已经用到了资源,本文就来详细的记录一下WPF中的资源.我们平时的“资源”一词是指“资财之源”,是创造人类社会财富的源泉.在计算机程 ...
- 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异
编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异 题目挺绕口的.C++ 11的好东西不算太多,但变参模板(Variadic Template)肯定是其中耀眼的一 ...
- 《深入浅出WPF》 学习笔记
<深入浅出WPF> 序言 1. 什么是WPF 2. 为什么要学习WPF 第一章 XAML概览 1. XAML是什么? 2. XAML有哪些优点 第二章 从零起步认识XAML 1. 新 ...
- 微信小程序新闻列表功能(读取文件、template模板使用)
微信小程序新闻列表功能(读取文件.template) 不忘初心,方得始终.初心易得,始终难守. 在之前的项目基础上进行修改,实现读取文件内容作为新闻内容进行展示. 首先,修改 post.wxml 文件 ...
- ArcGIS API for Silverlight代码中使用Template模板
原文:ArcGIS API for Silverlight代码中使用Template模板 在项目开发中,会遇到点选中聚焦闪烁效果,但是因为在使用Symbol的时候,会设置一定的OffSetX和OffS ...
- WPF 详解模板
在WPF中有三大模板 ControlTemplate,ItemsPanelTemplate,DataTemplate.其中ControlTemplate和 ItemsPanelTemplate是控件模 ...
- 【【分享】深入浅出WPF全系列教程及源码
】
因为原书作者的一再要求,在此声明,本书中的部分内容引用了原书名为<深入浅出WPF>的部分内容,假设博文不能满足你现有的学习须要,能够购买正版图书! 本人10月份提出离职,可是交接非常慢,预 ...
- 《深入浅出WPF》笔记——绘画与动画
<深入浅出WPF>笔记——绘画与动画 本篇将记录一下如何在WPF中绘画和设计动画,这方面一直都不是VS的强项,然而它有一套利器Blend:这方面也不是我的优势,幸好我有博客园,能记录一 ...
随机推荐
- C++多态中虚函数表合并与继承问题
多态: C++的多态是通过一张虚函数表(Virtual Table)来实现的,简称为 V-Table.在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承.覆写的问题,保证其真实反应实际的函数. ...
- Java HdAcm1069
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { Lis ...
- 使用Hugo和GitHub搭建博客
折腾了几天博客的框架终于搭建起来了.研究了一番之后,最终还是选择使用Hugo和GitHub来搭建博客.本文介绍了如何使用Hugo来搭建静态博客网站,并将其部署在GitHub上.使用https://&l ...
- 批量修改Linux密码脚本(Python)
搭建环境 centos 7.4 使用脚本 python 批量修改connect用户的密码 生成密码为随机密码 保存为xls文档 #!/usr/bin/env python # -*- coding: ...
- 关闭Redis服务
方式1: 方式2:
- K8S_第一课作业_20200407
(1)通过cgroup来限制memory ##消耗内存脚本 /tmp/xmem.sh #!/bin/bash mkdir /tmp/memory mount -t tmpfs -o size=2048 ...
- AI学习1
什么是AI: 功能介绍:是一种应用于出版.多媒体和在线图像的工业标准矢量插画的软件,是一款非常好的矢量图形处理工具应用:标志设计.字体设计.印刷出版.海报书籍排版.专业插画.多媒体图像处理和互联网页面 ...
- 阶段总结-Java基础-超进阶
Gitee项目地址:https://gitee.com/zc10010/java_interview_guide/tree/master/知识点话术 项目叫话术,但是我觉得作为知识点学习是挺不错的. ...
- 排查dubbo接口重复注销问题,我发现了一个巧妙的设计
背景 我在公司内负责自研的dubbo注册中心相关工作,群里经常接到业务方反馈dubbo接口注销报错.经排查,确定是同一个接口调用了两次注销接口导致,由于我们的注册中心注销接口不能重复调用,调用第二次会 ...
- 远程桌面连接(mstsc)全攻略
打算从今天开始,写一写我经常用的,有长时间使用经验的东西,与大家分享,就从mstsc开始吧! mstsc应该是在Windows中,除了calc.cmd.notepad.mspaint,我使用率最高的系 ...