2009-07-03 8 views
17

Ich versuche den Inhalt eines Einkaufswagens in ItemsControl(ListBox). Dazu habe ich erstellt die folgenden DataTemplate:Wie DockPanel füllen verfügbaren Speicherplatz

<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> 

Wenn die Einzelteile in meinem Warenkorb jedoch angezeigt werden, der Name und Preis TextBlocks sitzen direkt nebeneinander, und es gibt eine sehr große Menge an Whitespace auf der rechten Seite.

Fragen Sie sich, was die beste Methode, um die DockPanel zu dehnen, um den gesamten Raum von der ListItem zur Verfügung gestellt wurde füllen zu füllen?

Antwort

26

Bind die Width des DockPanel zum ActualWidth des ListBoxItem:

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

Eine weitere Option: Sie könnten nur die ItemContainerStyle so neu zu definieren, dass die ListBoxItem horizontal gestreckt wird:

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

Ich habe versucht, mit, dass die Bindung und es scheint, die ListBoxItem zu verursachen ständig in der Größe zu wachsen, wenn sie mit Snoop sehen, sah ich die Breite sowohl das ListBoxItem und die DockPanel 300.000 übersteigen. –

+0

Versuchen Sie, an die ActualWidth der ListBox selbst zu binden, dann ... –

+2

Oh, ok, ich bekomme es ... Sie müssen LastChildFill = "False" auf dem DockPanel setzen, sonst wird der zweite TextBlock gestreckt –

4

DockPanel s sind böse. Die Versuchung, die StackPanel/DockPanel Kombination für komplexe Layouts zu verwenden, führt zu "Layout-Sackgassen". Verwenden Sie ein Grid:

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

Ich benutze Grid fast ausschließlich s, ein separates Gitter für jeden Block von Elementen, dass „zusammengehören“

+0

Ich denke nicht, dass DockPanels böse sind, sie können manchmal ziemlich nützlich sein ... aber ich muss zustimmen, dass es wahrscheinlich nicht die beste Option in diesem Fall war –

+0

Natürlich ist das subjektiv und sie sind kein _absolutes_ Böses;) Aber schau wo Rich schon hingeht - mit ItemContainerStyle (semi-advanced stuff) für einfache Aufgabe - irgendwie bezeichnend ... –

+0

hatte ich mir zu Anfang ein Grid gedacht. Bei einer engen ListBox oder einem ausreichend langen Wert für die Eigenschaften Name oder Price überlappen sich die beiden TextBlocks jedoch mit ihren Werten. Außerdem würde ich kaum zwei TextBlocks an den gegenüberliegenden Enden eines Panels als "komplexes Layout" klassifizieren. –

5

Das schöne an Dock-Panels ist sie bereits alle verfügbaren Raum füllen . LastChildFill ist standardmäßig true (aber ich lege es zur Verdeutlichung unten an), also setze das DockPanel-Attribut nicht auf das letzte Kind und es füllt den verfügbaren Platz.

<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> 
Verwandte Themen