zoukankan      html  css  js  c++  java
  • 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

     

     

     

     

     

     

     

     

  • 相关阅读:
    Django学习-9-ORM多对多操作
    Django学习-8-模板渲染的一些特性
    Django学习-7-ORM操作
    Django学习-6-路由系统
    Hadoop 知识
    最全的Spark基础知识解答
    windows server 2008 R2 远程连接用户数修改
    Windows 2008 R2 SP1部署WSUS 3.0 SP2
    Windows Server2008 R2 设置NAT 让Hyper-V连接Internet
    免费好用的Microsoft iSCSI Software Target 3.3
  • 原文地址:https://www.cnblogs.com/YangMark/p/3154375.html
Copyright © 2011-2022 走看看