• WPF DataTemplate與ControlTemplate


    一. 前言

        什麼是DataTemplate? 什麼是ControlTemplate? 在stackoverflow有句簡短的解釋 "A DataTemplate, therefore, is used to provide visual structure for underlying data, while a ControlTemplate has nothing to do with underlying data and simply provides visual layout for the control itself."
       
        意思是說,DataTemplate被使用在提供底層的數據;ControlTemplate則被使用在對控件本身可見布局的樣式。因此關於DataTelmplate與ControlTemplate的不同之處,我們應該從控件是如何使用著手。
     
     
    二. Control, ContentControl, and ItemsControl
     
        由下面三個邏輯樹,可知道ContentControl與ItemsControl均繼承自Control。而Control又繼承FrameworkElement,莫名奇妙的我們又多了一個問題-為什麼控件都要繼承FrameworkElement呢?
     
     
     
        
    FrameworkElement具備以下幾點特性:
    1.布局(Layout):定義了MaxHeight與MinHeight等屬性,故當我們呼叫控件時,控件本身即會在UI上佔位。
    2.生命週期事件:定義Loaded/UnLoaded等事件,可通知後端控件何時被加載。
    3.DataContext:在MVVM設計模式下,我們通常會使用DataContext綁定我們的ViewModel,DataContext屬性就是由FrameworkElement所提供。 
    故控件均具有以上特性,因此我們能直接呼叫控件,並知道何時應該被加載。
     
    以下是WPF中常使用的控件之結構樹狀圖
     
     
     
    三. DataTemplate and ControlTemplate
      上一章介紹完一些控件的特性以及附屬關係,現在該思考的是我們如何使用這些控件呢??如:ListBox出現時,我們需要的是底層數據能展示在UI上(DataTemplate);Button有時或許我們會希望能修改事件觸發(IsPress or IsMouseOver)的結果(ControlTemplate)。
      因此我們可以說兩者最大的不同在於DataTemplate服務於無形的數據, ControlTemplate則服務於有形的Control。而ControlTemplate還有一個特別重要的屬性-Triggers, 我們可藉由Triggers控制Control本身的屬性。
    以下將以Button為例,分別在DataTemplate與ControlTemplate中加上同樣的樣式, 我們就可以知道兩者的不同了。
     
    DataTemplate
                <Button> 
                    <Button.ContentTemplate>
                        <DataTemplate>
                            <Grid>
                                <Ellipse Width="100" Height="100" x:Name="ellipse">
                                    <Ellipse.Fill>
                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                            <GradientStop Offset="0" Color="blue"/>
                                            <GradientStop Offset="1" Color="LightBlue"/>
                                        </LinearGradientBrush>
                                    </Ellipse.Fill>
                                </Ellipse>
                                <Ellipse Width="80" Height="80">
                                    <Ellipse.Fill>
                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                            <GradientStop Offset="0" Color="White"/>
                                            <GradientStop Offset="1" Color="Transparent"/>
                                        </LinearGradientBrush>
                                    </Ellipse.Fill>
                                </Ellipse>
                            </Grid>
                        </DataTemplate>
                    </Button.ContentTemplate>
                </Button>

     

    ControlTemplate

                <Button> 
                    <Button.Template>
                        <ControlTemplate TargetType="Button">
                            <Grid>
                                <Ellipse Width="100" Height="100" x:Name="ellipse">
                                    <Ellipse.Fill>
                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                            <GradientStop Offset="0" Color="blue"/>
                                            <GradientStop Offset="1" Color="LightBlue"/>
                                        </LinearGradientBrush>
                                    </Ellipse.Fill>
                                </Ellipse>
                                <Ellipse Width="80" Height="80">
                                    <Ellipse.Fill>
                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                            <GradientStop Offset="0" Color="White"/>
                                            <GradientStop Offset="1" Color="Transparent"/>
                                        </LinearGradientBrush>
                                    </Ellipse.Fill>
                                </Ellipse>
                            </Grid>
                        </ControlTemplate>
                    </Button.Template>
                </Button>

    發現了嗎??

    同樣的樣式,在DataTemplate與ControlTemplate卻有不同的結果。

    DataTemplate存在於ContentTemplate中, 所修改的樣式僅修改Button中Content的樣式。而ControlTemplate卻將Button整個樣式修改掉了。

    回到我們一開始說的,DataTemplate服務於無形的數據(Data), ControlTemplate則服務於有形的Control。

     

    參考資料

    1. ControlTemplate & DataTemplate

    2. WPF : ControlTemplate和DataTemplate的区别

    3. Difference between Control Template and DataTemplate in WPF

     

     

     

     

     

     

     

     

  • 相关阅读:
    No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
    deep-in-es6(二)
    jQuery插件--根据数据加载的进度动画案例
    shop--14.升级--本地账号注册,登录,修改密码
    shop--13.升级--Redis缓存技术
    JedisUtil工具类
    shop--12.升级--加密数据库明文密码
    shop--11.阿里云部署java网站与微信开发调试
    shop--10.店铺详情(后台+前端类似于shoplist)
    shop--10.店铺列表(前端)
  • 原文地址:https://www.cnblogs.com/YangMark/p/3154375.html
Copyright © 2020-2023  润新知