Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

WPF : Les modèles de contenus et les Templates des contrôles

On ne vas pas s'arréter en si bon chemin. Je vais maintenant parler de modèles de contenu de WPF.

Une des grandes nouveautés de WPF, c'est le fait que les contrôles soient "sans aspects". En effet, avec WinForms, vous aviez à votre disposition un contrôle ListBox, pour mettre du texte dedans. Mais si un jour vous voulez mettre dans votre ListBox des CheckBox, il fallait redévelopper un nouveau contrôle qui gère ça.

Sous WPF, les contrôles sont totalement dissociés de leur apparence. Un contrôle ne représente qu'un comportement. Par exemple une ListBox, c'est un contrôle (un ItemsControl, pour être plus précis, mais on va voir ça juste après) qui gère la selection d'un (ou plusieurs) élément et le défilement. Après si vous voulez faire une ListBox en 3D qui contient des images et des CheckBox, c'est tout à fait possible (enfin, je crois... :-D). Pareil pour le Button, c'est un contrôle qui gère l'évènement du click. Mais vous pouvez lui donner la forme que vous voulez.

Architecture de WPF

Je ne vais pas m'attarder sur toutes ces classes. Sachez simplement que FrameworkElement est la classe de base pour tout élément de votre interface : les Panel (Canvas, DockPanel, StackPanel...), les Shape (Rectangle, Ellipse...), et bien sûr les Control (et quelques autres classes). FrameworkContentElement, son "jumeau" gère lui plutôt le contenu (comme un TextBlock). Par contre, il ne dérive pas de Visual comme FrameworkElement.

Un object qui dérive de Control gère véritablement des interactions. Ce n'est pas le cas pour les objets dérivant juste de FrameworkElement, un Rectangle par exemple ne gère pas d'intéraction, il sert juste à s'afficher.

Les contrôles

Les contrôles sont divisés en 5 catégories :

  • Control
  • ContentControl (Button, CheckBox, Window)
  • ItemsControl (ListBox)
  • HeaderedContentControl (TabItem)
  • HeaderedItemsControl (MenuItem, ToolBar)

Suivant le type de contrôle que vous voudez faire, vous dériverez d'une de ces 5 classes. Chacun de ces 5 classes ont un modèle de contenu différent. Le Control n'a pas de contenu. Le ContentControl peut contenir un unique objet en tant que contenu, le ItemsControl peut contenir une collection d'objet en tant que contenu.

Le contenu d'un contrôle peut être du texte (facile), d'autres UIElement, ou même des objets complètement quelconque (j'ai déjà un peu parlé de ça dans cet article).

Je vais maintenant expliquer comment est défini le graphisme des ContentControl et des ItemsControl.

Le ContentControl

Vous pouvez personnaliser 2 choses avec un ContentControl :

  • le Template : l'apparence du contrôle
  • le ContentTemplate : la façon dont le contenu est affiché

Le Template permet de définir l'apparence qu'a votre contrôle :

<ContentControl.Template>

  <
ControlTemplate TargetType="{x:Type ContentControl}"
>
    <
Border BorderThickness="2" BorderBrush="Green" Padding="5" Margin="5" Background="LightGreen"
>
      <
DockPanel
>
        <
TextBlock Text="Template (ControlTemplate)" FontSize="12" DockPanel.Dock="Top"
/>
        <ContentPresenter
/>
      </
DockPanel
>
    </
Border
>
  </ControlTemplate
>

</
ContentControl.Template>

Vous définissez une apparence, et vous placez quelque part un ContentPresenter. C'est à l'endroit où est placé le ContentPresenter que le contenu du contrôle est affiché. Simple non ?

Vous pouvez aussi personnaliser la façon dont est affichés le contenu. Si le contenu est un objet qui dérive de UIElement, par défaut, WPF affichera le contenu tel qu'il doit l'être (normal). Par contre si le contenu ne dérive pas de UIElement, vous pouvez fournir à WPF un ContentTemplate qui indique comment "transformer" l'objet en un UIElement (puisque c'est la seule chose que WPF puisse afficher).

<ContentControl.ContentTemplate>

  <
DataTemplate
>
    <StackPanel
>
      <
TextBlock Text="ContentTemplate (DataTemplate)" FontSize="12"
/>
      <
Button Content="{Binding}"
/>
    </
StackPanel
>
  </DataTemplate
>

</
ContentControl.ContentTemplate>

Le ItemsControl

Pour l'ItemsControl, vous pouvez personnaliser 3 choses :

  • le Template : l'apparence du contrôle
  • le ItemsPanel : le Panel qui contiendra le contenu
  • le ItemTemplate : la façon dont le contenu est affiché

Pour le ItemsControl, vous pouvez de la même façon définir la propriété Template à l'aide d'un ControlTemplate, mais cette fois-ci, vous devrez indiquer l'emplacement du contenu non pas à l'aide de ContentPresenter mais de ItemsPresenter :

<ItemsControl.Template>

  <
ControlTemplate TargetType="{x:Type ItemsControl}">

    <
Border BorderThickness="2" BorderBrush="Green" Padding="5" Margin="5" Background="LightGreen">
      <
DockPanel
>
        <
TextBlock Text="Template (ControlTemplate)" FontSize="12" DockPanel.Dock="Top"
/>
        <ItemsPresenter
/>
      </
DockPanel
>
    </
Border
>
  </ControlTemplate
>

</
ItemsControl.Template>

Pour le ContentControl, il n'y avait qu'un seul UIElement à afficher. Ici il peut y en avoir plusieurs (puisque je vous rappelle que le ItemsControl a pour contenu une collection). Donc l'ItemsPresenter n'affiche pas directement le contenu, mais il l'affiche à l'interieur d'un Panel. Vous pouvez définir quel Panel utiliser grâce à ItemsPanelTemplate :

<ItemsControl.ItemsPanel>

  <
ItemsPanelTemplate
>
    <
UniformGrid Rows="2" Columns="3"
/>
  </
ItemsPanelTemplate
>

</
ItemsControl.ItemsPanel>

Enfin, comme pour le ContentControl, vous pouvez donner à WPF un DataTemplate définissant la façon dont les données sont affichée via la propriété ItemTemplate. Ce DataTemplate sera appliqué pour chaque objet de la collection :

<ItemsControl.ItemTemplate>

  <
DataTemplate
>
    <
Border BorderBrush="Blue" BorderThickness="2" Padding="5" Margin="1" Background="LightSkyBlue"
>
      <
StackPanel
>
        <
TextBlock Text="ItemTemplate (DataTemplate)" FontSize="12"
/>
        <Button Content="{Binding Path=.Action}"
/>
      </
StackPanel
>
    </
Border
>
  </
DataTemplate
>

</
ItemsControl.ItemTemplate>

Vous pouvez donc vraiment personnaliser totalement l'apparence de vos contrôles et définir des styles pour permettre à votre application de changer de style en un clin d'oeil.

Publié lundi 24 juillet 2006 15:30 par RaptorXP
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

# WPF : Article sur les mod&amp;#232;les de contenus et templates

Pour ceux que &#231;a int&#233;resse, je viens de poster un article sur les mod&#232;les de contenus dans WPF et les...
lundi 24 juillet 2006 17:00 by Code is poetry
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01