2009-07-03 12 views
17

J'essaie le contenu d'un panier dans un ItemsControl(ListBox). Pour ce faire, je l'ai créé les éléments suivants DataTemplate:Comment faire pour remplir DockPanel espace disponible

<DataTemplate x:Key="Templates.ShoppingCartProduct" 
       DataType="{x:Type viewModel:ProductViewModel}"> 
    <DockPanel HorizontalAlignment="Stretch"> 
     <TextBlock DockPanel.Dock="Left" 
        Text="{Binding Path=Name}" 
        FontSize="10" 
        Foreground="Black" /> 
     <TextBlock DockPanel.Dock="Right" 
        Text="{Binding Path=Price, StringFormat=\{0:C\}}" 
        FontSize="10" 
        Foreground="Black" /> 
    </DockPanel> 
</DataTemplate> 

Lorsque les éléments sont affichés dans mon panier cependant, le nom et le prix TextBlocks sont assis juste à côté de l'autre, et il y a une très grande quantité de espace blanc sur le côté droit.

Je me demandais quelle était la meilleure méthode pour forcer le DockPanel à étirer pour remplir tout l'espace mis à disposition par le ListItem était?

Répondre

26

Liez le Width du DockPanel au ActualWidth du ListBoxItem:

<DockPanel Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"> 
... 

Une autre option: vous pouvez simplement redéfinir la ItemContainerStyle de sorte que la ListBoxItem est étirée horizontalement:

<ListBox.ItemContainerStyle> 
    <Style TargetType="ListBoxItem"> 
     <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
    </Style> 
</ListBox.ItemContainerStyle> 
+0

J'essayé d'utiliser que la liaison et il semble être la cause du ListBoxItem de croître continuellement en taille, lors de la visualisation avec Snoop, j'ai vu la largeur des deux la ListBoxItem et DockPanel dépasse 300 000. –

+0

Essayez de vous lier à l'ActualWidth de la ListBox lui-même, puis ... –

+2

Oh, ok, je comprends ... vous devez définir LastChildFill = "False" sur le DockPanel, sinon le second TextBlock est étiré –

4

DockPanel s sont mauvais. La tentation d'utiliser la combinaison StackPanel/DockPanel pour les mises en page complexes conduit à des «impasses de mise en page». Utilisez une grille:

<Grid> 
    <TextBlock HorizontalAlignment="Left" 
... 
    <TextBlock HorizontalAlignment="Right" 
... 
/Grid> 

J'utilise Grid s presque exclusivement, à l'aide d'une grille séparée pour chaque bloc d'éléments qui « appartiennent ensemble »

+0

Je ne pense pas que les DockPanels soient malfaisants, ils peuvent être très utiles parfois ... mais je dois convenir que ce n'était probablement pas la meilleure option dans ce cas –

+0

Bien sûr, c'est subjectif et ils ne sont pas un mal absolu;) Mais regardez où Rich va déjà - en utilisant ItemContainerStyle (truc semi-avancé) pour une tâche simple - un peu indicative ... –

+0

J'avais considéré une Grille au début. Cependant, étant donné un ListBox étroit, ou une valeur suffisamment longue pour les propriétés Name ou Price, les deux TextBlocks finiront par chevaucher leurs valeurs. En outre, je classerais difficilement deux TextBlocks aux extrémités opposées d'un panneau en tant que «mise en page complexe». –

5

La bonne chose à propos des panneaux de quai est qu'ils remplissent déjà tout l'espace disponible . LastChildFill est vrai par défaut (mais je l'ai défini ci-dessous pour plus de clarté), donc ne définissez pas l'attribut DockPanel sur le dernier enfant, et cela remplira l'espace disponible.

<DockPanel HorizontalAlignment="Stretch" LastChildFill="true"> 
    <TextBlock DockPanel.Dock="Left" 
       Text="{Binding Path=Name}" 
       FontSize="10" 
       Foreground="Black" /> 
    <TextBlock 
       Text="{Binding Path=Price, StringFormat=\{0:C\}}" 
       FontSize="10" 
       Foreground="Black" /> 
</DockPanel> 
Questions connexes