I recently need to display a set of items in a ListBox in a grid that wrapped based on the width of the ListBox. Simple right?
My XAML started out something like this:
<Grid x:Name="LayoutRoot">
<ListBox Margin="170,57,134,150">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<Button Width="75" Content="Button"/>
<Button Width="75" Content="Button"/>
<Button Width="75" Content="Button"/>
<Button Width="75" Content="Button"/>
<Button Width="75" Content="Button"/>
</ListBox>
</Grid>
and it produced the following result:
Notice how the 5th button is cutoff and is not wrapping. For awhile I was stumped and started looking at ways to modify the WrapPanel itself. One solution might be to give the WrapPanel a fixed width, but that is not very elegant. The solution I landed on (and what I believe to be the correct solution) is to disable the Horizontal Scrolling functionality on the ListBox.
The XAML changes to this:
<Grid x:Name="LayoutRoot">
<ListBox Margin="170,57,134,150" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<Button Width="75" Content="Button"/>
<Button Width="75" Content="Button"/>
<Button Width="75" Content="Button"/>
<Button Width="75" Content="Button"/>
<Button Width="75" Content="Button"/>
</ListBox>
</Grid>
The attached ScrollViewer.HorizontalScrollbarVisibility property tells the Scrollviewer the ListBox (and thus its containing panel) not to scroll horizontally. Thus the WrapPanel doesn’t assume it has an infinite width (this is a non-developer interpretation of what is going on).
The result is just what I want:
Hope this helps!