1. templatepart
TemplatePart(部件)是指ControlTemplate中的命名元素。控件逻辑预期这些部件存在于ControlTemplate中,并且通过
protected DependencyObject GetTemplateChild(String childName)获取它们后进行操作。
以AutoSuggestBox为例,它的ControlTemplate结构如下,可以看到AutoSuggestBox由四个TemplatePart组成,每个TemplatePart都可以在控件代码中以编程方式访问:
下图显示了AutoSuggestBox的TemplatePart:
![[UWP 自定义控件]了解模板化控件(4):TemplatePart](https://img.php.cn/upload/article/001/503/042/175841372030472.jpg)
2. 使用TemplatePart
上一篇文章构造了一个很基础的控件HeaderedContentControl,这次通过扩展这个类做些实验性的功能来介绍模板化控件的进阶知识。
新建一个名为ContentView的控件,继承自HeaderedContentControl,它要实现的功能有两个:
- 控件的Header默认Opacity=0.7,当鼠标移动到控件上时,设置Header的Opacity=1。
- 当Header为空时,隐藏用于显示Header的HeaderContentPresenter。
虽然可以使用依赖属性及TemplateBinding的方式实现这个需求,不过这次用TemplatePart的方式实现。很显然,要实现这次的需求最直接的做法是获取显示Header的TemplatePart,然后用代码对其进行操作。大致上分为两步:添加TemplatePart名称,在代码中获取这个部件并
操作。
2.1 添加TemplatePart名称
在ContentView的ControlTemplate中为ContentPresenter命名为HeaderContentPresenter:
<ContentPresenter Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" FontWeight="Normal" Foreground="{ThemeResource TextControlHeaderForeground}" Margin="0,0,0,8" x:Name="HeaderContentPresenter"></ContentPresenter>2.2 获取TemplatePart
模板化控件在加载ControlTemplate后会调用OnApplyTemplate,可以在这个函数中调用
protected DependencyObject GetTemplateChild(String childName)获取模板中指定名字的部件。从返回值是DependencyObject可以看出,只要是DependencyObject 都能使用ControlTemplate获取。
这段代码演示了如何获得显示Header的ContentPresenter部件:
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
_headerPart = GetTemplateChild(HeaderPartName) as FrameworkElement;
}由于Template可能多次加载,或者不能正确获取TemplatePart,所以使用TemplatePart前应该先判断是否为空;如果要订阅事件,应该先取消订阅。更完整的GetTemplateChild步骤应该是:
- 取消订阅TemplatePart事件
- 将TemplatePart存储到私有字段
- 订阅TemplatePart事件
可以参考如下代码:
多奥淘宝客程序API免费版 F8.0
多奥淘宝客程序免费版拥有淘宝客站点的基本功能,手动更新少,管理简单等优点,适合刚接触网站的淘客们,或者是兼职做淘客们。同样拥有VIP版的模板引擎技 术、强大的文件缓存机制,但没有VIP版的伪原创跟自定义URL等多项创新的搜索引擎优化技术,除此之外也是一款高效的API数据系统实现无人值守全自动 化运行的淘宝客网站程序。4月3日淘宝联盟重新开放淘宝API申请,新用户也可使用了
0
查看详情
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (_button != null)
{
_button.Click -= OnButtonClick;
}
_button = GetTemplateChild(PartButtonName) as ButtonBase;
if (_button != null)
{
_button.Click += OnButtonClick;
}
}2.3 完整的代码
[TemplatePart(Name = HeaderPartName, Type = typeof(FrameworkElement))]
public sealed class ContentView : HeaderedContentControl
{
public const string HeaderPartName = "HeaderContentPresenter";
public ContentView()
{
this.DefaultStyleKey = typeof(ContentView);
}
private FrameworkElement _headerPart;
private bool _isPointerEntered;
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
_headerPart = GetTemplateChild(HeaderPartName) as FrameworkElement;
UpdateHeaderVisual();
}
protected override void OnPointerEntered(PointerRoutedEventArgs e)
{
base.OnPointerEntered(e);
_isPointerEntered = true;
UpdateHeaderVisual();
}
protected override void OnPointerExited(PointerRoutedEventArgs e)
{
base.OnPointerExited(e);
_isPointerEntered = false;
UpdateHeaderVisual();
}
protected override void OnHeaderChanged(object oldValue, object newValue)
{
base.OnHeaderChanged(oldValue, newValue);
UpdateHeaderVisual();
}
private void UpdateHeaderVisual()
{
if (_headerPart == null)
return;
if (_isPointerEntered)
_headerPart.Opacity = 1;
else
_headerPart.Opacity = 0.7;
if (Header == null)
_headerPart.Visibility = Visibility.Collapsed;
else
_headerPart.Visibility = Visibility.Visible;
}
}3. x:DeferLoadStrategy="Lazy"与GetTemplateChild
标记为
x:DeferLoadStrategy="Lazy"的元素将延迟加载,即不会出现在VisualTree上,直到它被调用。
假设将ContentView中HeaderContentPresenter标记为
x:DeferLoadStrategy="Lazy"并且在代码中注释
_headerPart = GetTemplateChild(HeaderPartName) as FrameworkElement这句,运行时将看不到Header的内容,并且VisualTree如下所示:
![[UWP 自定义控件]了解模板化控件(4):TemplatePart](https://img.php.cn/upload/article/001/503/042/175841372194916.jpg)
只有代码中执行了
_headerPart = GetTemplateChild(HeaderPartName) as FrameworkElement这句后,VisualTree上才可以看到HeaderContentPresenter,如下所示:
![[UWP 自定义控件]了解模板化控件(4):TemplatePart](https://img.php.cn/upload/article/001/503/042/175841372135260.jpg)
出于性能方面的考虑,很多UWP原生控件都会包含
x:DeferLoadStrategy="Lazy"。
4. TemplatePartAttribute协定
有时,为了表明控件期待在ControlTemplate存在某个特定部件,防止编辑ControlTemplate的开发人员删除它,控件上会添加TemplatePartAttribute协定。上面的ContentView代码中即包含这个协定:
[TemplatePart(Name = HeaderPartName, Type = typeof(FrameworkElement))]
这段代码的意思是期待在ControlTemplate中存在名称为 "HeaderContentPresenter",类型为FrameworkElement的部件。
TemplatePartAttribute在UWP中的作用好像被弱化了,不止在UWP原生控件中见不到TemplatePartAttribute,甚至在Blend中“部件”窗口也消失了。可能UWP更加建议使用VisualState。
5. 原则
使用TemplatePart需要遵循以下原则:
- 尽可能减少TemplatePartAttribute协定。
- 在使用TemplatePart之前检查其是否为Null。
- 如果ControlTemplate没有遵循TemplatePartAttribute协定也不应该抛出异常,有可能ControlTemplate的作者是故意屏蔽某项功能。
以上就是[UWP 自定义控件]了解模板化控件(4):TemplatePart的详细内容,更多请关注其它相关文章!
# 重启
# 衢州网络营销seo
# 重庆网络推广与seo
# 外贸网站如何做优化
# 门关键词排名方便云速捷
# 农机通网站建设素材视频
# 酒吧营销人抖音怎么做推广
# 阿坝有名的网络推广营销
# 浙江公司营销策划推广
# 世界足球关键词排名查询
# 吉林seo软件方案招聘
# 为空
# 这句
# windows
# 所示
# 可选
# 这段
# 闲时
# 加载
# 自定义
# 淘宝
# blend
# red
# 延迟加载
# app
相关栏目:
【
企业资讯168 】
【
行业动态50218 】
【
媒体报道120512 】
相关推荐:
固态硬盘如何外接
j*a怎么求数组均值
苹果16有哪些黑科技
bugly是什么
夸克文字口令是什么意思
折叠屏手机为什么有黑点
五十铃x-power是什么意思
vs怎么编写typescript
电动车power灯亮红灯是什么意思
如何发挥固态硬盘性能
夸克前缀后缀什么意思啊
put linux命令如何书写
路亚竿上的power是什么意思
路由器power闪红绿灯闪是什么意思
如何找出命令行
如何弄坏固态硬盘
typescript要用什么工具
品道音响上的power键是什么意思
sqlite中datediff函数怎么用 SQLite中DATEDIFF()函数的用法分享
考勤机power红灯是什么意思
typescript在浏览器里怎么用
md5解密是什么意思
春运抢票软件哪个最好用
苹果手机16有哪些功能
跑分是什么意思
如何为服务器配置静态路由?服务器配置静态路由详细教程
固态硬盘如何启动
折叠屏有哪些手机
为什么用typescript
单片机面包板怎么插
单片机蜂鸣器响了怎么停
苹果16主打颜色有哪些
12306退票手续费最新规定
电动车充电器上的power是什么意思
夸克加载什么要会员
苹果16新增哪些功能
一秒是多少毫秒
市盈率亏损是什么意思
如何查看邮件域名解析
虚拟机如何用命令清除垃圾
通配符的用法
苹果16系统有哪些改变
课程伴侣电脑怎么登录
early什么意思
如何用命令提示符显示隐藏分区
单片机怎么控制闪烁技术
soup是什么意思
春运抢票多久能知道成功
域名批量查询工具有哪些
juice是什么意思


