2009-11-27 10 views
20

Récemment, j'essaie de réutiliser certains éléments de l'interface utilisateur dans mon application. Quand j'ai commencé à programmer avec WPF, on m'a dit que DataTemplate est le meilleur moyen de réutiliser les éléments de l'interface utilisateur. Vous pouvez définir un modèle pour votre entité de données et l'utiliser partout. Cela semble très bien. Cependant, j'ai aussi trouvé quelques inconvénients, surtout quand on compare avec UserControl.WPF, UserControl ou DataTemplate

  1. Vous ne pouvez pas réutiliser un DataTemplate défini dans une autre fenêtre ou UserControl. Par exemple, si UserDataTemplate est défini dans WindowA.xaml, vous ne pouvez pas l'utiliser dans WindowB.xaml. La solution peut être de placer le DataTemplate en tant que ressource dans un dictionnaire de ressources global.
  2. Il est difficile d'avoir du code derrière DataTemplate. Comme mentionné à l'item 1, si vous mettez le DataTemplate dans un ResourceDictionary, il n'y a pas de place pour mettre votre code par défaut. J'ai googlé le problème et oui, j'ai trouvé une astuce pour que ResourceDictionary ait un fichier cs. Mais il a encore un autre problème.
  3. Un autre problème de DataTemplate est que vous devez être clair avec la différence entre l'instance de DataTemplate elle-même et les instances du contenu de DataTemplate. Un DataTemplate aura une seule "instance de DataTemplate" et peut avoir plusieurs instances du contenu de DataTemplate. Laissez-moi vous expliquer avec un exemple:

    <DataTemplate> 
         <DataTemplate.Resources> 
           <my:User x:key="User1"/> 
         </DataTemplate.Resources>     
         <Grid MouseLeftButtonDown="OnMouseLeftButtonDown"> 
           <Grid.Resources> 
             <my:User x:key="User2"/> 
           </Grid.Resources> 
         </Grid>   
    </DataTemplate> 
    
    
    public partial class CodeBehind 
    { 
         Point mousePos = new Point(); 
    
         private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
         { 
           mousePos = e.Pos...; 
         } 
    } 
    

Le résultat sera que: User1 n'aura un cas cependant, une instance Utilisateur2 sera créé une fois que le DataTemplate est appliqué, ce qui signifie que l'utilisateur 2 aura plusieurs instances si le datatemplate est appliqué plusieurs fois. Cependant, contrairement à UserControl, le champ "mousePos" n'aura PAS beaucoup de copies. Si le DataTemplate est appliqué 100 fois, le mousePos n'aura pas 100 copies, ce qui signifie que les 100 Grids utiliseront le seul champ mousePos en même temps, ce qui peut causer des problèmes. Dans UserControl, le champ que vous avez défini ne sera utilisé que par le contrôle. 100 instances UserControl auront 100 copies de champ. Peut-être que j'utilise DataTemplate dans le mauvais sens. Tout commentaire est apprécié.

Meilleures salutations,

Zach

Répondre

25

Conceptuellement DataTemplates et UserControls résolvent deux problèmes différents. Ils ne sont pas vraiment interchangeables, donc vos comparaisons ne sont pas vraiment précises.DataTemplates sont tous sur l'application d'un style visuel à un DataType

Généralement, cela signifie que j'ai ma propre classe .NET appelée Foo et je veux lui donner un style visuel. Je le ferais en créant un DataTemplate avec un DataType de Foo.

Je peux ensuite placer ce DataTemplate dans mon application (disons dans App.XAML) et j'obtiendrai mon style visuel appliqué à mon objet de données Foo où que ce soit. Cela signifie souvent que vous verrez un ContentControl qui a une propriété Content liée à une propriété de type Foo.

UserControls sur l'autre avait tout sur l'organisation de XAML. Un contrôle utilisateur aide à organiser des segments de code XAML que vous souhaitez réutiliser dans toute votre application et dont les comportements et les fonctionnalités sont liés. C'est plus que ce qu'un DataTempate fera. Un DataTemplate est lié à un DataType et affiche un visuel pour ce type. Un UserControl peut être composé de plusieurs DataTypes et peut inclure des comportements personnalisés. Cela étant dit, je trouve très rarement le besoin d'un contrôle UserControl. J'utilise partout des DataTemplates pour modéliser mes données et implémenter mes comportements à travers les liaisons de données et le pattern MVVM.

2

A propos 2.

Je dirais que DataTemplates ne sont pas conçus pour être utilisés avec le code-behind. Vous pouvez utiliser uniquement DataBinding et Commands pour câbler la logique entre votre modèle et sa représentation. Ne pas avoir de code-behind facilite également les tests unitaires de votre application.

10

Personnellement, je crée un contrôle UserControl, puis j'en crée un DataTemplate. Cela a pour moi les avantages suivants:

  1. Peut être utilisé sur plusieurs fenêtres, uniquement en redéfinissant la partie DataTemplate.
  2. Peut utiliser le code-behind (je sais, je sais, mais certaines choses sont tellement plus faciles en utilisant le code-behind, je ne vois pas l'intérêt de compliquer inutilement mon code basé sur le dogme).
  3. Prise en charge du concepteur XAML.