25

I'm trying the content of a shopping cart in an ItemsControl(ListBox). To do so, I've created the following DataTemplate:

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

When the items are displayed in my shopping cart however, the Name and Price TextBlocks are sitting right beside one another, and there is an extremely large amount of whitespace on the right hand side.

Was wondering what the best method to force the DockPanel to stretch to fill all the space made available by the ListItem was?

3 Answers 3

33

Bind the Width of the DockPanel to the ActualWidth of the ListBoxItem:

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

Another option: you could just redefine the ItemContainerStyle so that the ListBoxItem is stretched horizontally:

<ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="HorizontalContentAlignment" Value="Stretch"/> </Style> </ListBox.ItemContainerStyle> 
Sign up to request clarification or add additional context in comments.

8 Comments

I tried using that binding and it seems to be causing the ListBoxItem to continually grow in size, when viewing with Snoop, I saw the width of both the ListBoxItem and the DockPanel exceed 300,000.
Oh, ok, I get it... you must set LastChildFill="False" on the DockPanel, otherwise the second TextBlock is stretched
I ended up locating your second approach and going that route.
the 2nd approach works if you use HorizontalContentAlignment instead of HorizontalAlignment. I edited the answer.
The first approach does not work if your ListBox is resized down. The actual size stays at its maximal value.
|
11

The nice thing about dock panels is they already fill all the available space. LastChildFill is true by default (but I set it below for clarity), so just don't set the DockPanel attribute on the last child, and it will fill the available space.

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

Comments

10

DockPanels are evil. Temptation to use StackPanel/DockPanel combination for complex layouts leads to "layout dead ends". Use a Grid:

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

I use Grids almost exclusively, using a separate grid for each block of elements that "belong together"

6 Comments

I don't think DockPanels are evil, they can be pretty useful sometimes... however I must agree that it was probably not the best option in that case
Of course this is subjective and they are not an absolute evil ;) But look where Rich already going - using ItemContainerStyle (semi-advanced stuff) for simple task - kinda indicative...
I had considered a Grid at the outset. However, given a narrow ListBox, or long enough value for the Name or Price properties the two TextBlocks will end up overlapping their values. In addition I would hardly classify laying out two TextBlocks at opposite ends of a panel as a "complex layout".
Sorry for commenting to this old post, but using a grid is also a simple and equally effective solution to the problem. The overlap problem is avoidable. +1
This is an old answer, but I thought I'd point out that the problem with using a grid or panel in a ListBox's item template is that it's not one single element; it is a new element for each ListBoxItem and won't share the width of an other item unless explicitly set in the template. This makes setting the ItemContainerStyle content alignment to stretch a necessity when using a dynamic width.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.