zoukankan      html  css  js  c++  java
  • [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. 使用XamlReader

    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的根元素添加xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""

    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. 参考

    DataTemplate
    XamlReader
    x:FieldModifier

  • 相关阅读:
    [转]在自己的项目中调用别人的库的方法(static lib库,dynamic lib库以及dll动态库)
    前端、后台、客户端以及服务器
    C# 使用j
    C# Linq技术中SelectMany() 获取list对象的属性 汇总成为一个新的集合
    C# 集合的扩展方法-查询表达式GroupBy()的使用 转
    C# ASP.NET MVC中Filter过滤器的使用 通过注册到Global.asax注册为全局 过滤所有action
    C# ASP.NET MVC中有四种Filter 过滤器类型 通过标签 Attribute加到action上面
    C# 《Asp.Net Web Api 》-----路由机制 转
    C# ASP.NET MVC5路由系统机制详细讲解(转)
    MVC 自定义数据校验规则 Validation
  • 原文地址:https://www.cnblogs.com/dino623/p/Create-DataTemplate-Programatically.html
Copyright © 2011-2022 走看看