访问ControlTemplate内部的元素
需要用到code behind
注意要给需要访问的元素命名x:Name="PART_TextBlock"
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:CustomControlLib"><Style TargetType="{x:Type local:MyControl}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:MyControl}"><Border Background="{TemplateBinding Background}"BorderBrush="{TemplateBinding BorderBrush}"BorderThickness="{TemplateBinding BorderThickness}"><StackPanel><TextBlock x:Name="PART_TextBlock" /></StackPanel></Border></ControlTemplate></Setter.Value></Setter></Style> </ResourceDictionary>
custom control的程序部分 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes;namespace CustomControlLib {public class MyControl : Button{private const string TextBlockPart = "PART_TextBlock";TextBlock textBlock;static MyControl(){DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));}public override void OnApplyTemplate() //OnApplyTemplate get called everytime a template is applied to the control,control update {base.OnApplyTemplate(); //Button有自己的OnApplyTemplate我们需要call这个beofre call我们自己写的OnApplyTemplate方法if (textBlock != null) //避免memory leak每次call OnApplyTemplate方法时都给同一个textBlock加上event {textBlock.TextInput -= new TextCompositionEventHandler(textBlock_TextInput);}textBlock = GetTemplateChild(TextBlockPart) as TextBlock;if (textBlock != null){textBlock.Text = "Set from code";textBlock.TextInput +=new TextCompositionEventHandler(textBlock_TextInput);}}private void textBlock_TextInput(object sender, TextCompositionEventArgs e){}} }
使用该control<Window x:Class="CustomControlDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:cc="clr-namespace:CustomControlLib;assembly=CustomControlLib"Title="MainWindow"Width="525"Height="350"><Grid><cc:MyControl /></Grid> </Window>
改进:上面的方法不好,设想如果controlTemaplte里有很多element都需要访问,每一个元素都需要后台程序这样访问的话,会很乱
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes;namespace CustomControlLib {[TemplatePart(Name = TextBlockPart, Type = typeof(TextBlock))] //告诉使用template的作者这里x:Name为PART_TextBlock的control一定要是TextBlock类型的public class MyControl : Button{private const string TextBlockPart = "PART_TextBlock";TextBlock _textBlock; //避免每一次call OnApplyTemplate都在方法体里创建一个TextBlock,在方法前定义一个变量来储存protected TextBlock TextBlock{get {return _textBlock; }set{if (_textBlock != null) //避免memory leak每次call OnApplyTemplate方法时都给同一个textBlock加上event {_textBlock.TextInput -= new TextCompositionEventHandler(textBlock_TextInput);}_textBlock = value;if (_textBlock != null){_textBlock.Text = "Set from code";_textBlock.TextInput += new TextCompositionEventHandler(textBlock_TextInput);}}}static MyControl(){DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));}public override void OnApplyTemplate() //OnApplyTemplate get called everytime a template is applied to the control,control update {base.OnApplyTemplate(); //Button有自己的OnApplyTemplate我们需要call这个beofre call我们自己写的OnApplyTemplate方法 TextBlock = GetTemplateChild(TextBlockPart) as TextBlock; //每次call都赋值属性 }private void textBlock_TextInput(object sender, TextCompositionEventArgs e){}} }
TemplatePart(Name="PART_Decrease", Type=typeof(RepeatButton))
一直没明白这是干嘛用的,搜了一下,记载一下。
以Button的定义为例:
namespace System.Windows.Controls {// Summary:// Represents a button control, which reacts to the Click event.[TemplatePart(Name = "Normal State", Type = typeof(Storyboard))][TemplatePart(Name = "MouseOver State", Type = typeof(Storyboard))][TemplatePart(Name = "RootElement", Type = typeof(FrameworkElement))][TemplatePart(Name = "Pressed State", Type = typeof(Storyboard))][TemplatePart(Name = "FocusVisualElement", Type = typeof(UIElement))][TemplatePart(Name = "Disabled State", Type = typeof(Storyboard))]public class Button : ButtonBase{// Summary:// Initializes a new instance of the Button class.public Button();// Summary:// Apply a template to the Button.protected override void OnApplyTemplate();//// Summary:// Called when the IsEnabled property changes.//// Parameters:// isEnabled:// New value of the IsEnabled property.protected override void OnIsEnabledChanged(bool isEnabled);} }
[TemplatePart(Name = "Normal State", Type = typeof(Storyboard))] 这种东东是做什么用的 , 其实这是一种契约 , 是一种推荐的控件设计模式(只是推荐) , 意思是告诉要来写ControlTemplate的用户 , 你的ControlTemplate中需要有一个x:Name为“Normal State” , 类型为Storyboard , 当然这个类型可以是继承来的, 为什么一定要包含这些契约规定的元素 , 因为逻辑部分对这些东西进行了引用,它们将对控件的默认行为起着关键作用, 可以理解为这个控件的最基本元素 , 是实现默认行为的最小集合, 自然,你的ControlTemplate中如果没有包含契约中的内容 , 则相应的逻辑将无法实现。
所以说白了,就是提示用的.....这么写比较规范。
转载于:https://www.cnblogs.com/shawnzxx/p/3262095.html
访问ControlTemplate内部的元素相关推荐
- linux访问网页元素,Linux_DOM和JAVASCRIPT访问页面上的元素,访问方法:getElementById() - phpStudy...
DOM和JAVASCRIPT访问页面上的元素 访问方法: getElementById():返回拥用传递给该方法的指定id的第一个对象的引用. getElementsByName():返回拥用传递该方 ...
- SpringBoot中访问Thymeleaf提示:元素类型 meta 必须由匹配的结束标记终止。
场景 新建SpringBoot项目后整合Thymelaf后访问页面提示: 元素类型 "meta" 必须由匹配的结束标记 "</meta>" 终止. ...
- 用JS访问iframe中的元素
用JS访问iframe中的元素 1.首先,如何访问iframe中的元素?见如下代码: (1)1.htm源码: <input type=button value="test" ...
- STL 容器和迭代器连载8_访问顺序容器的元素
2019独角兽企业重金招聘Python工程师标准>>> /*- ========================================================== ...
- 【matlab】访问结构体内部元素
[matlab]访问结构体内部元素 语法格式: 结构体名称.字段名: 如果给域换新值则: 结构体名称.字段名=新值: 例如:person.weight; 具体情况我们看一下代码: >> s ...
- jQuery 学习-DOM篇(二):jQuery 在 DOM 内部插入元素
推荐阅读 Helm3(K8S 资源对象管理工具)视频教程:https://edu.csdn.net/course/detail/32506 Helm3(K8S 资源对象管理工具)博客专栏:https: ...
- 【云原生 • Kubernetes】认识 k8s 网络、外部网络访问 k8s 内部服务
目录 一.认识 Kubernetes 网络 二.外部网络如何访问 k8s 内部服务 1. NodePort 2. Load Balancer 3. Ingress 一.认识 Kubernetes 网络 ...
- teamviewer v_p_n+xp v_p_n服务实现在家访问公司内部局域网
原文地址:teamviewer v_p_n+xp v_p_n服务实现在家访问公司内部局域网 我的需求与作者是一样一样的,公司工作机IP为172.16.136.x,公司服务器IP有172.16.136. ...
- 华为WeLink钉钉企业微信飞书等,通过竹云IDaaS,访问企业内部应用及SaaS应用
背景@TOC 钉钉.企业微信.飞书.华为WeLink等,通过竹云IDaaS,访问企业内部应用及SaaS应用 背景 随着移动办公的需求,华为WeLink.钉钉.企业微信.飞书等移动办公App在各行各业中 ...
- 基于C#的AutoCAD二次开发之获取用户输入信息、选择集、访问CAD内部命令
基于C#的AutoCAD二次开发之获取用户输入信息.选择集.访问CAD内部命令 在CAD创建图形对象时,经常需要和用户进行交互,例如:直线创建时需要用户输入起点和终点(或长度)信息,复制对象时需要指定 ...
最新文章
- JVM与Dalvik
- 强制杀oracle进程
- 19、任务十八——事件委托、数组处理
- 计算机公开课教学反思,语文公开课教学反思
- LeetCode 656. 金币路径(DP)
- tensorflow基础:tf.data.Dataset.from_tensor_slices() 与 tf.data.Dataset.from_generator()的异同
- 轻量级的移动开发JavaScript框架-zepto.js
- JAVA毕设项目图书馆预约占座系统(java+VUE+Mybatis+Maven+Mysql)
- 工程图学与计算机绘图考查,工程图学与计算机绘图
- 计算机老出现安全警报怎么办,windows安全警报怎么关闭,教您怎么关闭windows安全警报...
- Solidity语言详解——view和pure函数的使用区别
- python正则匹配连续相同字符_正则表达式: 匹配n个相同连续字符
- @RunWith和@ContextConfiguration的用法
- 『转』为什么中国的程序员总被称为码农?
- Mysql隔离级别、锁及死锁
- 省钱第一步,华为云为您服务|和车神哥一起薅羊毛
- 《C语言程序设计(第三版)》苏小红 习题六 答案
- JavaScript 模块化介绍
- 电子会议桌牌或将替代纸质桌牌标签
- 国内的Internet九大骨干网是哪些网络
热门文章
- 七日Python之路--第十一天
- 蓝桥杯“基础练习: 十六进制转十进制
- 用arp-scan扫描局域网IP地址
- android studio actionbar,Android Studio环境下ActionBar的使用教程以及如何解决遇到的问题...
- python使用struct处理二进制数据(使用pack和unpack进行打包和解包)
- html里面怎么引入swiper,JavaScript库——使用swiper.js创建嵌套的swiper
- java r日历系统_Java GrerorianCalendar 实现日历查询
- python装饰器两层和三层_2020 python学习第十六天————三层装饰器与迭代器
- [转载]Java多线程——创建线程池的几个核心构造参数
- select2 清除已选项