2009-07-03 12 views
17

Estoy probando el contenido de un carrito de compras en un ItemsControl(ListBox). Para ello, he creado la siguiente DataTemplate:Cómo hacer que DockPanel complete el espacio 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> 

Cuando los elementos se muestran en mi carro de la compra sin embargo, el nombre y el precio TextBlocks están sentados justo al lado uno del otro, y hay una cantidad extremadamente grande de espacios en blanco en el lado derecho.

¿Se preguntaba cuál era el mejor método para forzar al DockPanel a estirar para llenar todo el espacio disponible por el ListItem?

Respuesta

26

Enlace el Width del DockPanel a la ActualWidth del ListBoxItem:

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

Otra opción: sólo podría redefinir el ItemContainerStyle para que el ListBoxItem se estira horizontalmente:

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

He intentado utilizar que la unión y parece ser la causa de la ListBoxItem a crecer continuamente en tamaño, cuando se ve con Snoop, vi el ancho tanto de la ListBoxItem y la DockPanel exceda de 300.000. –

+0

Intenta vincular al Actual Ancho del ListBox, entonces ... –

+2

Oh, vale, ya entendí ... debes establecer LastChildFill = "False" en el DockPanel, de lo contrario, el segundo TextBlock se alarga –

4

DockPanel s son malvados La tentación de usar la combinación StackPanel/DockPanel para diseños complejos conduce a "callejones sin salida de diseño". Utilizar una cuadrícula:

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

utilizo Grid s casi exclusivamente, usando una rejilla separada para cada bloque de elementos que "van de la mano"

+0

No creo que los DockPanels sean malos, a veces pueden ser muy útiles ... Sin embargo, debo aceptar que probablemente no fue la mejor opción en ese caso –

+0

Por supuesto, esto es subjetivo y no es un mal absoluto;) Pero miren hacia donde Rich ya está yendo - usando ItemContainerStyle (cosas semi-avanzadas) para tareas simples - un poco indicativo ... –

+0

Yo había considerado una Grilla desde el principio. Sin embargo, dado un ListBox estrecho, o un valor suficientemente largo para las propiedades de Nombre o Precio, los dos TextBlocks terminarán superponiendo sus valores. Además, difícilmente clasifico la instalación de dos TextBlocks en extremos opuestos de un panel como un "diseño complejo". –

5

Lo bueno de acoplar paneles es que ya llenan todo el espacio disponible . LastChildFill es verdadero de manera predeterminada (pero lo configuré a continuación para mayor claridad), así que no configure el atributo DockPanel en el último elemento secundario y llenará el espacio 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> 
Cuestiones relacionadas