ความแตกต่างระหว่างเทมเพลตควบคุมและ DataTemplate ใน WPF


คำตอบ:


267

โดยทั่วไปแล้วการควบคุมจะแสดงผลเพื่อประโยชน์ของตนเองและไม่สะท้อนข้อมูลพื้นฐาน ตัวอย่างเช่น a Buttonจะไม่ถูกผูกไว้กับวัตถุทางธุรกิจ - มันมีอย่างหมดจดเพื่อให้สามารถคลิก ContentControlหรือListBoxแต่ปกติจะปรากฏขึ้นเพื่อให้พวกเขาสามารถนำเสนอข้อมูลสำหรับผู้ใช้

A DataTemplateจึงถูกใช้เพื่อจัดเตรียมโครงสร้างการมองเห็นสำหรับข้อมูลพื้นฐานในขณะที่ a ControlTemplateไม่เกี่ยวข้องกับข้อมูลพื้นฐาน

ControlTemplateโดยทั่วไปจะมีเพียงTemplateBindingการแสดงออกผูกพันกลับไปที่คุณสมบัติในการควบคุมตัวเองในขณะที่DataTemplateจะมีการแสดงออกเข้าเล่มมาตรฐานผูกพันกับคุณสมบัติของตนDataContext(ธุรกิจ / วัตถุโดเมนหรือดูรุ่น)


21
มันสมเหตุสมผลไหม ฉันเดาว่าฉันกำลังพยายามอธิบายความแตกต่างทางปรัชญามากกว่าความแตกต่างทางเทคนิค
Matt Hamilton

110

โดยทั่วไปแล้ว a จะControlTemplateอธิบายวิธีแสดงตัวควบคุมในขณะที่ a DataTemplateอธิบายวิธีแสดงข้อมูล

ตัวอย่างเช่น:

A Labelคือตัวควบคุมและจะรวมสิ่งControlTemplateที่บอกว่าLabelควรแสดงโดยใช้Borderเนื้อหาบางส่วน ( DataTemplateหรือตัวควบคุมอื่น)

Customerชั้นข้อมูลและจะแสดงการใช้DataTemplateซึ่งอาจจะพูดเพื่อแสดงCustomerประเภทเป็นStackPanelที่มีสองTextBlocksหนึ่งในการแสดงชื่อและที่อื่น ๆ ที่แสดงหมายเลขโทรศัพท์ มันอาจจะเป็นประโยชน์ที่จะทราบว่าชั้นเรียนทั้งหมดจะแสดงโดยใช้DataTemplatesคุณมักจะใช้แม่แบบเริ่มต้นซึ่งเป็นที่TextBlockมีTextคุณสมบัติตั้งค่าเป็นผลมาจากToStringวิธีการของวัตถุ


โหวตเพื่อความเรียบง่ายของคำอธิบาย ชื่นชมมาก
Pete Magsig

31

Troels Larsenมีคำอธิบายที่ดีเกี่ยวกับฟอรัม MSDN

<Window x:Class="WpfApplication7.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <DataTemplate x:Key="ButtonContentTemplate">
      <StackPanel Orientation="Horizontal">
        <Grid Height="8" Width="8">
          <Path HorizontalAlignment="Stretch" 
           Margin="0,0,1.8,1.8" 
           VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 
           Data="M0.5,5.7 L0.5,0.5 L5.7,0.5"/>
          <Path HorizontalAlignment="Stretch" 
           Margin="2,3,0,0" 
           VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 
           Data="M3.2,7.5 L7.5,7.5 L7.5,3.5"/>
          <Path HorizontalAlignment="Stretch" 
           Margin="1.2,1.4,0.7,0.7" 
           VerticalAlignment="Stretch" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000" 
           Data="M2.5,2.5 L7.5,7.5"/>
          <Path HorizontalAlignment="Stretch" 
           Margin="1.7,2.0,1,1" 
           VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" 
           Data="M3,7.5 L7.5,7.5 L7.5,3.5"/>
          <Path HorizontalAlignment="Stretch" 
           Margin="1,1,1,1" 
           VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" 
           Data="M1.5,6.5 L1.5,1 L6.5,1.5"/>
        </Grid>
        <ContentPresenter Content="{Binding}"/>
      </StackPanel>
    </DataTemplate>
    <ControlTemplate TargetType="Button" x:Key="ButtonControlTemplate">
      <Grid>
        <Ellipse Fill="{TemplateBinding Background}"/>
        <ContentPresenter HorizontalAlignment="Center"
              VerticalAlignment="Center"/>
      </Grid>
    </ControlTemplate>
  </Window.Resources>
  <StackPanel>
    <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="1"/>
    <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="2"/>
    <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="3"/>
  </StackPanel>
</Window>

(เทมเพลตถูกขโมยอย่างโจ่งแจ้งจาก http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx และ http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx ตามลำดับ)

อย่างไรก็ตาม ControlTemplate จะพิจารณาว่าปุ่มมีลักษณะอย่างไรในขณะที่ ContentTemplate จะตัดสินว่ามีลักษณะของปุ่มอย่างไร ดังนั้นคุณสามารถผูกเนื้อหากับหนึ่งในคลาสข้อมูลของคุณและนำเสนอตัวเองตามที่คุณต้องการ


19

ControlTemplate: แสดงถึงรูปแบบการควบคุม

DataTemplate: แสดงถึงรูปแบบข้อมูล (คุณต้องการแสดงข้อมูลของคุณอย่างไร)

การควบคุมทั้งหมดกำลังใช้แม่แบบการควบคุมเริ่มต้นที่คุณสามารถแทนที่ผ่านคุณสมบัติแม่แบบ

ตัวอย่างเช่น
Buttonแม่แบบเป็นแม่แบบการควบคุม Buttonเทมเพลตเนื้อหาเป็นเทมเพลตข้อมูล

<Button   VerticalAlignment="Top" >
    <Button.Template>
        <ControlTemplate >
            <Grid>
                <Rectangle Fill="Blue" RadiusX="20" RadiusY="20"/>
                <Ellipse Fill="Red" />
                <ContentPresenter Content="{Binding}">
                    <ContentPresenter.ContentTemplate>
                        <DataTemplate>
                        <StackPanel Orientation="Horizontal" Height="50">
                            <TextBlock Text="Name" Margin="5"/>
                                <TextBox Text="{Binding UserName, Mode=TwoWay}" Margin="5" Width="100"/>
                            <Button Content="Show Name" Click="OnClickShowName" />
                        </StackPanel>
                    </DataTemplate>
                    </ContentPresenter.ContentTemplate>
                </ContentPresenter>
            </Grid>
        </ControlTemplate>
    </Button.Template>
</Button>

public String UserName
{
    get { return userName; }
    set
    {
        userName = value;
        this.NotifyPropertyChanged("UserName");
    }
}

7

ControlTemplate- การเปลี่ยนรูปลักษณ์ขององค์ประกอบ ตัวอย่างเช่นButtonสามารถมีภาพและข้อความ

DataTemplate - การแทนข้อมูลพื้นฐานโดยใช้องค์ประกอบ


1

ControlTemplateกำหนดลักษณะที่ปรากฏของภาพDataTemplateแทนที่ลักษณะที่ปรากฏของรายการข้อมูล

ตัวอย่าง: ฉันต้องการแสดงปุ่มจากสี่เหลี่ยมผืนผ้าเป็นวงกลม form => เทมเพลตการควบคุม

และถ้าคุณมีวัตถุที่ซับซ้อนในการควบคุมมันก็แค่เรียกและแสดงToString()โดยDataTemplateคุณสามารถรับสมาชิกหลายคนและแสดงและเปลี่ยนค่าของวัตถุข้อมูล


0

คำตอบทั้งหมดข้างต้นนั้นยอดเยี่ยม แต่มีความแตกต่างที่สำคัญที่พลาด ที่ช่วยในการตัดสินใจที่ดีขึ้นเกี่ยวกับเมื่อใช้อะไร มันเป็นItemTemplateคุณสมบัติ:

  • DataTemplate ใช้สำหรับองค์ประกอบที่ให้คุณสมบัติ ItemTemplateสำหรับคุณเพื่อแทนที่เนื้อหาของรายการโดยใช้DataTemplates ที่คุณกำหนดก่อนหน้านี้ตามข้อมูลที่ถูกผูกไว้ผ่านตัวเลือกที่คุณให้ไว้

  • แต่ถ้าการควบคุมของคุณไม่ได้ให้ความหรูหรานี้สำหรับคุณแล้วคุณยังสามารถใช้ที่สามารถแสดงเนื้อหาจากที่กำหนดไว้ล่วงหน้าContentView ControlTemplateที่น่าสนใจคุณสามารถเปลี่ยนControlTemplateคุณสมบัติของของคุณContentViewที่รันไทม์ อีกสิ่งหนึ่งที่ควรทราบว่าไม่เหมือนกับตัวควบคุมที่มีItemTemplateคุณสมบัติคุณไม่สามารถมีตัวควบคุมTemplateSelectorสำหรับ (ContentView) นี้ อย่างไรก็ตามคุณยังสามารถสร้างทริกเกอร์เพื่อเปลี่ยนControlTemplateat runtime

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.