Diferencia entre plantilla de control y plantilla de datos en WPF

Respuestas:

267

Normalmente, un control se representa por sí mismo y no refleja los datos subyacentes. Por ejemplo, un Buttonno estaría vinculado a un objeto comercial, está allí solo para que se pueda hacer clic en él. A ContentControlo ListBox, sin embargo, generalmente aparecen para que puedan presentar datos para el usuario.

A DataTemplate, por lo tanto, se utiliza para proporcionar una estructura visual para los datos subyacentes, mientras que a ControlTemplateno tiene nada que ver con los datos subyacentes y simplemente proporciona un diseño visual para el control en sí.

A ControlTemplategeneralmente solo contendrá TemplateBindingexpresiones, vinculando de nuevo a las propiedades del control en sí, mientras DataTemplateque contendrá expresiones de enlace estándar, vinculando a las propiedades de su DataContext(el objeto de negocio / dominio o modelo de vista).

Matt Hamilton
fuente
21
¿Eso tiene sentido? Supongo que estoy tratando de explicar las diferencias filosóficas en lugar de las técnicas.
Matt Hamilton
110

Básicamente, ControlTemplatedescribe cómo mostrar un Control, mientras que DataTemplatedescribe cómo mostrar Datos.

Por ejemplo:

A Labeles un control e incluirá un ControlTemplateque dice que Labeldebe mostrarse utilizando un Bordercontenido (un DataTemplatecontrol u otro).

Una Customerclase es Datos y se mostrará usando una DataTemplateque podría decir que muestra el Customertipo como que StackPanelcontiene dos, TextBlocksuno que muestra el Nombre y el otro que muestra el número de teléfono. Puede ser útil tener en cuenta que todas las clases se muestran usando DataTemplates, por lo general, usará la plantilla predeterminada que es una TextBlockcon la Textpropiedad establecida como resultado del ToStringmétodo del Objeto .

Bryan Anderson
fuente
Votado por la simplicidad de la descripción. Muy apreciado.
Pete Magsig
31

Troels Larsen tiene una buena explicación en el foro de 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>

(Plantillas robadas de http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx y http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx respectivamente)

De todos modos, ControlTemplate decide cómo se ve el botón, mientras que ContentTemplate decide cómo se ve el contenido del botón. Por lo tanto, puede vincular el contenido a una de sus clases de datos y hacer que se presente como lo desee.

onmyway133
fuente
19

ControlTemplate: Representa el estilo de control.

DataTemplate: Representa el estilo de datos (¿Cómo le gustaría mostrar sus datos?).

Todos los controles utilizan una plantilla de control predeterminada que puede anular mediante la propiedad de plantilla.

Por ejemplo, la
Button plantilla es una plantilla de control. Buttonplantilla de contenido es una plantilla de datos

<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");
    }
}
dijo saad
fuente
7

ControlTemplate- Cambiar la apariencia del elemento. Por ejemplo Buttonpuede contener imagen y texto

DataTemplate - Representar los datos subyacentes utilizando los elementos.

Syed
fuente
1

ControlTemplateDEFINA la apariencia visual, DataTemplateREEMPLAZA la apariencia visual de un elemento de datos.

Ejemplo: quiero mostrar un botón de forma rectangular a círculo => Plantilla de control.

Y si tiene objetos complejos para el control, solo llama y muestra ToString(), con los DataTemplateque puede obtener varios miembros y mostrar y cambiar sus valores del objeto de datos.

nihnih
fuente
0

Todas las respuestas anteriores son geniales, pero hay una diferencia clave que se perdió. Eso ayuda a tomar mejores decisiones sobre cuándo usar qué. Es ItemTemplatepropiedad:

  • DataTemplate se utiliza para elementos que proporcionan la propiedad ItemTemplate para que pueda reemplazar el contenido de sus elementos utilizando DataTemplates que defina previamente de acuerdo con los datos vinculados a través de un selector que proporcione.

  • Pero si su control no le brinda este lujo , aún puede utilizar uno ContentViewque puede mostrar su contenido predefinido ControlTemplate. Curiosamente, puede cambiar la ControlTemplatepropiedad de suContentView en tiempo de ejecución. Una cosa más a tener en cuenta es que a diferencia de los controles con ItemTemplatepropiedad, no puede tener un TemplateSelectorcontrol para este (ContentView). Sin embargo, aún puede crear disparadores para cambiar el ControlTemplatetiempo de ejecución.

Ashi
fuente