Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Largeur de DataTemplate et Listbox

Une petite astuce rapide en passant…

Lorsque vous créez un DataTemplate qui sera utilisé comme ItemTemplate d’une ListBox vous avez certainement rencontré ce très désagréable problème : vos items sont bien affichés, cadrés à gauche, mais leur largeur est variable, elle s’adapte au contenu. Si votre template est en fond blanc sur une listbox en fond blanc aussi, on n’y verra que du blanc… Mais si votre template possède un fond ou un border par exemple, la listbox aura un aspect affreux avec des items en escalier, cadrés à gauche, mais avec une partie droite irrégulière…

En général on arrive à un résultat qui ressemble à cela :

Capture1

C’est franchement laid… Alors qu’on voudrait obtenir ça :

Capture2

Ce qui est déjà beaucoup plus agréable…

Le problème ne vient pas du DataTemplate, arrêtez de le martyriser, le pauvre n’y est pour rien !

j’ai vu des développeurs essayer de faire des Bindings relatifs de type FindAncestor pour remonter sur la listbox et se binder à son ActualWidth ou d’autres combines de ce genre qui ne donnent pas même entière satisfaction. Le problème est ailleurs… Laissez le DataTemplace et son contenu en mode “auto”, c’est ce qui est le mieux.

Pour résoudre cet épineux problème il faut comprendre que le DataTemplate n’est qu’un modèle et que lorsqu’il est instancié pour chaque item il est placé dans un conteneur généré pour l’occasion. C’est ce conteneur qui pause problème car il a un cadrage à gauche et non Stretch par défaut.

Comment l’atteindre et le modifier ? La méthode lourde consiste à modifier le Style de la listbox pour atteindre la propriété ItemContainerStyle et modifier ce dernier (un style aussi) afin de mettre HorizontalContentAlignment à Stretch.

Si vous devez créer un style pour votre ListBox, alors c’est le meilleur moyen. Sinon il existe une version courte : ajouter uniquement dans la listbox une modification directe de la propriété en question :

<ListBox ItemsSource="{Binding}"  Name="listBox1" 
   ItemTemplate="{DynamicResource PersonneTemplate}"  
HorizontalAlignment="Left"> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="HorizontalContentAlignment"
Value="Stretch"></Setter> </Style> </ListBox.ItemContainerStyle>
</ListBox>

La partie en gras (ItemContainerStyle) est celle qu’il faut ajouter à la définition de la listbox qui supportera un ItemTemplate personnalisé. Et vous voilà avec une belle listbox dont les items sont bien alignés et qui s’étalent sur toute la largeur de la listbox. Le tout sans bricolage, sans toucher au template, et en 4 lignes de Xaml.

Merci qui ?

Stay Tuned !

blog comments powered by Disqus