Diferença entre o modelo de controle e o DataTemplate no WPF

Respostas:

267

Normalmente, um controle é renderizado por si só e não reflete dados subjacentes. Por exemplo, um Buttonnão seria vinculado a um objeto de negócios - ele existe apenas para que ele possa ser clicado. A ContentControlou ListBox, no entanto, geralmente aparecem para que eles possam apresentar dados para o usuário.

A DataTemplate, portanto, é usado para fornecer estrutura visual aos dados subjacentes, enquanto a ControlTemplatenão tem nada a ver com os dados subjacentes e simplesmente fornece layout visual para o próprio controle.

A ControlTemplategeralmente conterá apenas TemplateBindingexpressões, vinculando de volta às propriedades no controle em si, enquanto a DataTemplateconterá expressões de ligação padrão, vinculando-se às propriedades de seu DataContext(o objeto de negócios / domínio ou o modelo de exibição).

Matt Hamilton
fonte
21
Aquilo fez sentido? Acho que estou tentando explicar as diferenças filosóficas e não as técnicas.
Matt Hamilton
110

Basicamente, a ControlTemplatedescreve como exibir um controle, enquanto DataTemplatedescreve como exibir dados.

Por exemplo:

A Labelé um controle e incluirá um ControlTemplateque diz que Labeldeve ser exibido usando um Borderconteúdo em torno de algum (um DataTemplateou outro controle).

Uma Customerclasse é Data e será exibida usando um DataTemplateque poderia dizer exibir o Customertipo como um StackPanelcontendo dois, TextBlocksmostrando o Nome e o outro exibindo o número de telefone. Pode ser útil observar que todas as classes são exibidas usando DataTemplates, você geralmente usará o modelo padrão que é a TextBlockcom a Textpropriedade configurada para o resultado do ToStringmétodo do Objeto .

Bryan Anderson
fonte
Votou na simplicidade da descrição. Muito apreciado.
Pete Magsig 17/04
31

Troels Larsen tem uma boa explicação no fórum do 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>

(Modelos roubados descaradamente de http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx e http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx respectivamente)

De qualquer forma, o ControlTemplate decide a aparência do botão, enquanto o ContentTemplate decide a aparência do conteúdo do botão. Assim, você pode vincular o conteúdo a uma de suas classes de dados e apresentá-lo como quiser.

onmyway133
fonte
19

ControlTemplate: Representa o estilo de controle.

DataTemplate: Representa o estilo dos dados (como você gostaria de mostrar seus dados).

Todos os controles estão usando o modelo de controle padrão que você pode substituir pela propriedade do modelo.

Por exemplo,
Button modelo é um modelo de controle. Buttonmodelo de conteúdo é um modelo de dados

<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");
    }
}
disse saad
fonte
7

ControlTemplate- Alterando a aparência do elemento. Por exemplo, Buttonpode conter imagem e texto

DataTemplate - Representando os dados subjacentes usando os elementos.

Syed
fonte
1

ControlTemplateDEFINA a aparência visual, DataTemplateSUBSTITUI a aparência visual de um item de dados.

Exemplo: quero mostrar um botão de retangular para circular = = Modelo de Controle.

E se você tiver objetos complexos para o controle, ele apenas chama e mostra ToString(), com DataTemplatevocê pode obter vários membros e exibir e alterar seus valores do objeto de dados.

nihnih
fonte
0

Todas as respostas acima são ótimas, mas há uma diferença fundamental que foi perdida. Isso ajuda a tomar melhores decisões sobre quando usar o quê. É ItemTemplatepropriedade:

  • DataTemplate é usado para elementos que fornecem a propriedade ItemTemplate para você substituir o conteúdo de seus itens usando DataTemplates definidos anteriormente de acordo com os dados vinculados por meio de um seletor que você fornece.

  • Mas se o seu controle não fornecer esse luxo para você , você ainda poderá usar um ContentViewque possa exibir o conteúdo predefinido ControlTemplate. Curiosamente, você pode alterar a ControlTemplatepropriedade do seu ContentViewem tempo de execução. Mais uma coisa a observar que, diferentemente dos controles com ItemTemplatepropriedade, você não pode ter um TemplateSelectorpara esse controle (ContentView). No entanto, você ainda pode criar gatilhos para alterar o ControlTemplatetempo de execução.

Ashi
fonte