[UWP]如何使用代码创建DataTemplate(或者ControlTemplate)
1. 前言
在UWP中DataTemplate是一个十分重要的功能,并且几乎无处不在,例如DataGrid中的DataGridTemplateColumn:
<controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center">
<TextBlock Text="{x:Bind FirstName}" />
<TextBlock Text="{x:Bind LastName}" />
</StackPanel>
</DataTemplate>
</controls:DataGridTemplateColumn.CellTemplate>
而且DateTemplate(或ControlTemplate)极有可能需要由代码动态生成。
UWP大致上有两种使用代码生成DateTemplate的方式。
2. 使用资源字典
这其实并不是由代码动态生成DataTemplate,只是比较方便的从资源字典读取DataTemplate的邪道,一般来说不好意思暴露给项目外的用户。
创建一个UserControl,然后把父类从“UserControl”改为“ResourceDictionary”,然后在Xaml中编写DataTemplate,为这个DataTemplate的x:Name赋值,并且将x:FieldModifier改为“internal”(这样DataTemplate才可以作为一个字段被项目中的其它类访问),代码如下:
public sealed partial class XamlResource : ResourceDictionary
{
public XamlResource()
{
this.InitializeComponent();
}
}
<ResourceDictionary x:Class="App5.XamlResource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App5"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<DataTemplate x:Name="ItemTemplate"
x:FieldModifier="internal" >
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ResourceDictionary>
使用起来也很方便:
XamlResource resource = new XamlResource();
ListControl.ItemTemplate = resource.ItemTemplate;
这种做法的好处是编辑Datatemplate时有智能感知和属性面板,不容易出错;调用起来也很简单。虽然不够动态,但我常常使用这种方式创建DataTemplate。
3. 使用XamlReade
XamlReader用于解析XAML并创建相应的对象树。文档里给出的例子是构建一个Ellipse:
string xaml ="<Ellipse Name="EllipseAdded" Width="300.5" Height="200" Fill ="Red" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/>";
object ellipse = XamlReader.Load(xaml);
当然了,要在代码里构建一个Ellipse何必这样大费周章。对于XamlReader,我平时用得最多的就是用来创建DataTemplate和ControlTemplate这些不方便用代码构建的元素。记得在XAML的根元素添加<CODE>xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""</CODE>和<CODE>xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""</CODE>:
var template = (DataTemplate)XamlReader.Load(@"
<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
<TextBlock Text=""{Binding " + DisplayMemberPath + @"}"" VerticalAlignment=""Center""/>
</DataTemplate>");
ListControl.ItemTemplate = template;
这种方式满足了“动态”这个需求,缺点也很明显:动态的就容易出错,而且这种方式很难构建复杂的DataTemplate。
4. 结语
这两种方式我都很常用,复杂的就用资源字典方式,简单但需要动态的就用XamlReader。有些人会为XamlReader做得更多,例如通过反射将一个TextBlock转换为XAML,再使用XamlReader读取成DataTemplate。我觉得这样也不错,但我还没遇到过这种应用场景就不尝试了。
5. 参考
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 商业数据分析从入门到入职(5)Python基本语法和数据类型
- JavaScript 同步和异步的执行机制问题
- Vue 与小程序:父组件给子组件传值的区别
- Canvas悟空推箱子
- Spring Cloud 之服务网关 Zuul (一)
- React进阶篇(八)react redux
- 通过一个简单例子理解JavaScript闭包和this对象
- Spring Cloud 之服务网关 Gateway (一)
- Hacking with iOS: SwiftUI Edition - Hot Prospects项目(二)
- HarmonyOS-对Android开发者也太友好了吧
- 你还在使用复杂的 zkclient 开发 zookeeper 么?是时候用 Curator 了 !
- 如何通俗理解类和类型的差别?
- 如何理解变量?
- 装逼篇 | 抖音超火的九宫格视频是如何生成的,Python 告诉你答案
- 能否详细讲讲字符串呢?