浅谈WPF之各种Template

这篇具有很好参考价值的文章主要介绍了浅谈WPF之各种Template。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前几天写了一篇文章【浅谈WPF之控件模板和数据模板】,有粉丝反馈说这两种模板容易弄混,不知道什么时候该用控件模块,什么时候该用数据模板,以及template和itemtemplate之间的关系等,今天专门写一篇文章,简述WPF中各种模板及其相互关系。仅供学习分享使用,如有不足之处,还请指正。

浅谈WPF之各种Template

 

概述

在WPF中,一共有三种模板,分别如下:

  • 控件模板ControlTemplate,用来指定控件的呈现样式。
  • 数据模板DataTemplate,用来指定子项数据的呈现样式。
  • 子控件模板ItemPanelTemplate,用来指定子项控件的布局样式。

 

模板与控件之间的关系

 

关于各个模板与控件之间的关系,如下图所示:

浅谈WPF之各种Template

通过上图可以看出:

  1. Control拥有Template属性,是ControlTemplate类型,所有Control派生的子控件,都具有Template属性,都可以通过控件模板设置控件的样式。
  2. ContentControl拥有ContentTemplate属性,是DataTemplate类型,所有ContentControl派生的控件,都具有ContentTemplate属性,如Button,ListBoxItem,DataGridCell等。
  3. ItemsControl拥有ItemsTemplate属性,是DataTemplate类型,所有ItemsControl派生的控件,都具有ItemsTemplate属性,如ListBox,ComboBox,DataGrid,ListView等。
  4. ItemsControl拥有ItemsPanel属性,是ItemsPanelTemplate类型,所有ItemsControl派生的控件,都具有ItemsPanel属性,如ListBox,ComboBox,DataGrid,ListView等。
  5. Template,ContentTemplate,ItemsTemplate,ItemsPanel只是属性名称,而DataTemlate,ControlTemplate,ItemsPanelTemplate才是模板类型。

 

ControlTemplate控件模板详解

 

利用ControlTemplate可以彻底的颠覆控件的默认外观。<ControlTemplate>里面的内容就是视觉树VisualTree。
两个重要属性:

a)ContentPresenter

重定义控件模板,默认模板将会被覆盖,此时需要利用ContentPresenter,把原有模板的属性原封不动的投放到自定义模板中。

b)Triggers

触发器列表,里面包含一些触发器Trigger,我们可以定制这个触发器列表来使控件对外界的刺激发生反应,比如鼠标经过时文本变成粗体等。

控件模板示例

<Window x:Class="WpfApplication1.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
         Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ControlTemplate x:Key="rect" TargetType="{x:Type CheckBox}">
            <ControlTemplate.Resources>
                <SolidColorBrush x:Key="redBrush" Color="Red"/>
            </ControlTemplate.Resources>
            <StackPanel>
                <Rectangle Name="breakRectangle" Stroke="Red" StrokeThickness="2" Width="20" Height="20">
                    <Rectangle.Fill>
                        <SolidColorBrush Color="White"/>
                    </Rectangle.Fill>
                </Rectangle>
                <ContentPresenter/>
            </StackPanel>
            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter TargetName="breakRectangle" Property="Fill" Value="{StaticResource ResourceKey=redBrush}">
                    </Setter>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Window.Resources>
    <Canvas>
        <CheckBox Template="{StaticResource ResourceKey=rect}"  Content="我是CheckBox"/>
    </Canvas>
</Window>

注意:<ContentPresenter Margin="{TemplateBinding Padding}" /> 实现了将模板中的Margin绑定到原控件中的Padding上去。

将控件模板写到样式里面,如下所示:

<Style x:Key="cbx" TargetType="{x:Type CheckBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <ControlTemplate.Resources>
                    <SolidColorBrush x:Key="redBrush" Color="Red"/>
                </ControlTemplate.Resources>
                <StackPanel>
                    <Rectangle Name="breakRectangle" Stroke="Red" StrokeThickness="2" Width="20" Height="20">
                        <Rectangle.Fill>
                            <SolidColorBrush Color="White"/>
                        </Rectangle.Fill>
                    </Rectangle>
                    <ContentPresenter/>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter TargetName="breakRectangle" Property="Fill" Value="{StaticResource ResourceKey=redBrush}">
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

通过绑定样式资源,如下所示:

<CheckBox Style="{StaticResource ResourceKey=cbx}" Content="我是CheckBox"/>

 

c)ItemsPresenter

 

继承自ItemsControl的控件,有一个ItemsPanel属性作为集合元素承载容器。子元素ItemsPresenter负责呈现控件的任务。

只要把ItemsPresenter放在内部模板中,那么ItemsPresenter则会去检测父元素是否为集合控件,然后将ItemsPanel添加到其内部视觉树当中。

<Style x:Key="{x:Type ItemsControl}" TargetType="{x:Type ItemsControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ItemsControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Padding="{TemplateBinding Padding}"
                        SnapsToDevicePixels="true">
                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

比较常见的继承自ItemsControl的控件,比如ComboBox,ContextMenu,ListBox,DataGrid,ListView等。

 

DataTemplate数据模板详解

 

数据模板定义了数据的显示方式,也就是数据对象的可视结构。主要是可以自定义控件的同时进行数据绑定。

<Window x:Class="WpfApplication1.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:src="clr-namespace:WpfApplication1"
         Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ObjectDataProvider x:Key="personList" ObjectType="{x:Type src:PersonList}"/>
        <DataTemplate x:Key="rect">
            <Border Name="border" BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5">
                <StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}" Margin="5,0,0,0"/>
                        <TextBlock Text="{Binding Age}" Margin="5,0,0,0"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Address}" Margin="5,0,0,0"/>
                    </StackPanel>
                </StackPanel>
            </Border>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=personList}}"
                  ItemTemplate="{StaticResource ResourceKey=rect}"></ListBox>
    </Grid>
</Window>

注意这里在调用时应该绑定的是 ItemTemplate 属性。 

 

ItemPanelTemplate详解

 

首先我们要知道常见的条目控件有:ListBox,Menu,StatusBar等。

比如拿ListBox来说,ItemBox的ItemPanel其实是一个VisualizingStackPanel,就是说ListBox的每一项的排列方式是遵循StackPanel的

原则,也就是从上到下的排列方式。如果要实现从左到右排列:

<Window x:Class="WpfApplication1.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:src="clr-namespace:WpfApplication1"
         Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ObjectDataProvider x:Key="personList" ObjectType="{x:Type src:PersonList}"/>
        <DataTemplate x:Key="rect">
            <Border Name="border" BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5">
                <StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}" Margin="5,0,0,0"/>
                        <TextBlock Text="{Binding Age}" Margin="5,0,0,0"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Address}" Margin="5,0,0,0"/>
                    </StackPanel>
                </StackPanel>
            </Border>
        </DataTemplate>
        <ItemsPanelTemplate x:Key="items">
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        </ItemsPanelTemplate>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=personList}}"
                  ItemTemplate="{StaticResource ResourceKey=rect}" ItemsPanel="{StaticResource ResourceKey=items}"></ListBox>
    </Grid>
</Window>

也就是说,ItemsPanelTemplate可以用来定义集合控件的容器外观。

 

总结

 

1、Template


控件模板,是指整个控件的展示和布局。
如ComboBox,可分为文本区域,下拉按钮区域,Items的Popup区域。
Template就是管理这些位置的布局。

2、ItemsPresenter


可以简单理解为占位符,在样式中使用,标记着这个区域用来展示该控件的Items。
如:ComboBox的下拉列表的可选项。
但是,只负责显示,而不能管理如何显示,如果我们要内容横向排列,就要用到ItemsPanel。

3、ItemsPanel


管理Items的排列方式,如,ComboBox默认是竖直排列的,我们要横着排列,只需要定义ItemsPanel为WrapPanel,就可以了。
这时候Items的排列方式已经完成,如果还要让ComboBox的每个项都重写,比如,背景、图标等,就要用到ItemContainerStyle。

4、ItemContainerStyle


就是每个项的样式,自己重写,就可以定制出每个项的样式了。

以上就是浅谈WPF之各种模板的全部内容。文章来源地址https://www.toymoban.com/news/detail-747212.html

到了这里,关于浅谈WPF之各种Template的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 真会玩:莫言用ChatGPT为余华写了一篇获奖词

    5月16日,《收获》杂志65周年庆典暨新书发布活动在上海舞蹈中心举行。   典礼现场,余华凭借《文城》获得收获文学榜2021年长篇小说榜榜首。   作为老友,莫言在颁奖时故意卖了个关子:“这次获奖的是一个了不起的人物,当然了,他也是我的好朋友,他不一般,所以我

    2024年02月06日
    浏览(35)
  • 我用chatgpt写了一篇关于2023 it 行业的发展的论文……

    我用chatgpt写了一篇关于2023 it 行业的发展的论文。我将从以下几个方面来探讨2023年IT行业的发展: 1.云计算技术在IT行业的应用:随着云计算技术的发展,2023年IT行业将受益于云计算技术在数据存储、计算能力和安全性方面的优势。 2.大数据技术在IT行业的应用:大数据技术的

    2024年02月07日
    浏览(53)
  • c# wpf Template ContentTemplate

    1.概要 1.1 定义内容的外观 2.2 要点分析 2.代码 3.运行结果

    2024年04月09日
    浏览(40)
  • 我用GPT写了一个关于GPT的文章,大家看看写的如何

    目录 I. 引言 1.1 研究背景和意义 1.2 现有研究综述 II. ChatGPT技术介绍 2.1 ChatGPT技术原理 2.2 ChatGPT技术优势 III. ChatGPT技术在智能客服中的应用和挑战 3.1 ChatGPT技术在智能客服中的应用 3.2 ChatGPT技术在智能客服中面临的挑战 3.3 优化用户体验提升ChatGPT技术在智能客服中的作用 IV

    2024年02月07日
    浏览(123)
  • 浅谈CAS,一篇就够了

    wshanshi:喵桑说,我总结完CAS就带我去吃羊蝎子火锅…干饭那必须整起啊… CAS:Compare and Swap。从字面意义上来说,就是先进行比较,然后替换。 它是乐观锁思想的一种实现,尤其是在并发量大的业务场景下保证单个实例的原子性,使用较为频繁。java类库中java.util.concurrent.

    2024年03月13日
    浏览(43)
  • 浅谈 OI 中各种合并操作

    合并操作一直是 OI 中一大考点,今天请各位跟着笔者来梳理一下各种合并操作。 几乎可以说是最经典的合并了。 假定我们可以在 (O(k)) 的时间内往某个集合中插入一个数,那么我们就可以在 (O(n log n k)) 的时间内合并若干个 元素总量为 (n) 的集合。 看到查询绝对众数我

    2024年02月05日
    浏览(32)
  • 【python】我用python写了一个可以批量查询文章质量分的小项目(纯python、flask+html、打包成exe文件)

    web 效果预览: 先去质量查询地址:https://www.csdn.net/qc 输入任意一篇文章地址进行查询,同时检查页面,在Network选项下即可看到调用的API的请求地址、请求方法、请求头、请求体等内容: 请求头里面很多参数是不需要的,我们用 ApiPost 这个软件来测试哪些是必要参数。 经过

    2024年02月13日
    浏览(41)
  • 浅谈WPF之UI布局

    一个成功的软件,离不开人性化的UI设计,如何抓住用户第一视觉,让用户产生依赖感,合适优雅的布局必不可少。本文以一些简单的小例子,简述 WPF中布局 面板 控件 的使用 ,仅供学习分享使用,如有不足之处,还请指正。 在WPF中,关于布局面板控件,主要有以下几种:

    2024年01月25日
    浏览(35)
  • 浅谈Windows的各种“字符串”

    不知道你们的大学老师有没有说过 中文是用两个字节保存 ,直到我了解了字符编码,然后留下了这几行代码 结果很明显,不同的编码方式,中文所占字节也不一样 ,而这就要从 Windows 下的字符集说起。 说起Windows下的编程,可能大家的印象都是:微软从来都“特立独行”,

    2024年02月10日
    浏览(40)
  • 浅谈WPF之Popup弹出层

    在日常开发中,当点击某控件时,经常看到一些弹出框,停靠在某些页面元素的附近,但这些又不是真正的窗口,而是页面的一部分,那这种功能是如何实现的呢?今天就以一个简单的小例子,简述如何 在WPF开发中,通过Popup实现鼠标点击弹出浮动停靠窗口 ,仅供学习分享使

    2024年02月03日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包