Différence entre le modèle de contrôle et le modèle de données dans WPF

Réponses:

267

En règle générale, un contrôle est rendu pour lui-même et ne reflète pas les données sous-jacentes. Par exemple, un Buttonne serait pas lié à un objet métier - il est là uniquement pour qu'il puisse être cliqué. A ContentControlou ListBox, cependant, apparaissent généralement afin de pouvoir présenter des données pour l'utilisateur.

A DataTemplate, par conséquent, est utilisé pour fournir une structure visuelle pour les données sous-jacentes, tandis que ControlTemplatea n'a rien à voir avec les données sous-jacentes et fournit simplement une disposition visuelle pour le contrôle lui-même.

Un ControlTemplatene contiendra généralement que des TemplateBindingexpressions, se liant aux propriétés du contrôle lui-même, tandis qu'un DataTemplatecontiendra des expressions de liaison standard, se liant aux propriétés de son DataContext(objet métier / domaine ou modèle de vue).

Matt Hamilton
la source
21
Cela avait-il du sens? Je suppose que j'essaie d'expliquer les différences philosophiques plutôt que les différences techniques.
Matt Hamilton
110

Fondamentalement, un ControlTemplatedécrit comment afficher un contrôle tandis qu'un DataTemplatedécrit comment afficher des données.

Par exemple:

A Labelest un contrôle et comprendra un ControlTemplatequi indique que le Labeldoit être affiché à l'aide d'un Borderautour de certains contenus (un DataTemplateou un autre contrôle).

Une Customerclasse est Data et sera affichée en utilisant un DataTemplatequi pourrait dire d'afficher le Customertype comme StackPanelcontenant deux l' TextBlocksun indiquant le nom et l'autre affichant le numéro de téléphone. Il peut être utile de noter que toutes les classes sont affichées en utilisant DataTemplates, vous utiliserez généralement le modèle par défaut qui est un TextBlockavec la Textpropriété définie sur le résultat de la ToStringméthode de l'objet .

Bryan Anderson
la source
A voté pour la simplicité de la description. Très appréciée.
Pete Magsig
31

Troels Larsen a une bonne explication sur le forum 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>

(Modèles volés de manière flagrante sur http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx et http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx respectivement)

Quoi qu'il en soit, le ControlTemplate décide à quoi ressemble le bouton lui-même, tandis que le ContentTemplate décide à quoi ressemble le contenu du bouton. Vous pouvez donc lier le contenu à l'une de vos classes de données et le présenter tel que vous le souhaitez.

onmyway133
la source
19

ControlTemplate: Représente le style de contrôle.

DataTemplate: Représente le style de données (comment souhaitez-vous afficher vos données).

Tous les contrôles utilisent un modèle de contrôle par défaut que vous pouvez remplacer via la propriété du modèle.

Par exemple, le
Button modèle est un modèle de contrôle. Buttonle modèle de contenu est un modèle de données

<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");
    }
}
dit saad
la source
7

ControlTemplate- Changer l'apparence de l'élément. Par exemple, Buttonpeut contenir une image et du texte

DataTemplate - Représenter les données sous-jacentes à l'aide des éléments.

Syed
la source
1

ControlTemplateDÉFINIT l'apparence visuelle, DataTemplateREMPLACE l'apparence visuelle d'un élément de données.

Exemple: je veux montrer un bouton de forme rectangulaire à circulaire => Modèle de contrôle.

Et si vous avez des objets complexes à contrôler, il appelle et affiche simplement ToString(), avec DataTemplatevous pouvez obtenir différents membres et afficher et modifier leurs valeurs de l'objet de données.

nihnih
la source
0

Toutes les réponses ci-dessus sont excellentes mais il y a une différence clé qui a été manquée. Cela aide à prendre de meilleures décisions sur le moment d'utiliser quoi. C'est la ItemTemplatepropriété:

  • DataTemplate est utilisé pour les éléments qui fournissent la propriété ItemTemplate pour vous permettre de remplacer le contenu de ses éléments à l'aide de DataTemplates que vous définissez précédemment en fonction des données liées via un sélecteur que vous fournissez.

  • Mais si votre contrôle ne vous offre pas ce luxe, vous pouvez toujours utiliser un ContentViewqui peut afficher son contenu à partir de prédéfinis ControlTemplate. Fait intéressant, vous pouvez modifier la ControlTemplatepropriété de votre ContentViewau moment de l'exécution. Une dernière chose à noter que contrairement aux contrôles avec ItemTemplatepropriété, vous ne pouvez pas avoir de TemplateSelectorcontrôle pour ce contenu (ContentView). Cependant, vous pouvez toujours créer des déclencheurs pour modifier le ControlTemplateau moment de l'exécution.

Ashi
la source