Finally got something that works but it needs code. I agree with all of you when you say that we need to resize height of the WrapPanel to make that works. Here is my solution :
<ScrollViewer x:Name="scroll1" SizeChanged="ScrollViewer_SizeChanged" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<toolkit:WrapPanel x:Name="wp1" Orientation="Vertical" VerticalAlignment="Top" HorizontalAlignment="Left" ItemHeight="30" ItemWidth="250" >
<Button Content="1" />
<Button Content="2" />
<Button Content="3" />
<Button Content="4" />
<Button Content="5" />
<Button Content="6" />
<Button Content="7" />
<Button Content="8" />
</toolkit:WrapPanel>
</ScrollViewer>
Here is the CodeBehind :
private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
// Stupid magical number because ViewPortHeight is sometimes not accurate
Double MAGICALNUMBER = 2;
// Ensure ViewPortSize is not 0
if (scroll1.ViewportWidth <= MAGICALNUMBER || scroll1.ViewportHeight <= MAGICALNUMBER)
return;
Size contentSize = new Size(scroll1.ViewportWidth - MAGICALNUMBER, scroll1.ViewportHeight - MAGICALNUMBER);
Size itemSize = new Size(wp1.ItemWidth, wp1.ItemHeight);
Size newSize = CalculateSizeBasedOnContent(contentSize, wp1.Children.Count, itemSize);
wp1.Width = newSize.Width;
wp1.Height = newSize.Height;
}
private Size CalculateSizeBasedOnContent(Size containerSize, int itemsCount, Size itemSize)
{
int iPossibleColumns = (int)Math.Floor(containerSize.Width / itemSize.Width);
int iPossibleRows = (int)Math.Floor(containerSize.Height / itemSize.Height);
// If all items can fit in first column without scrolling (or if container is narrow than the itemWidth)
if (itemsCount <= iPossibleRows || containerSize.Width < itemSize.Width)
return new Size(itemSize.Width, (itemsCount * itemSize.Height));
// If all items can fit in columns without scrollbar
if (iPossibleColumns * iPossibleRows > itemsCount)
{
int columnsNeededForDisplay = (int)Math.Ceiling((itemsCount/(Double) iPossibleRows));
return new Size(columnsNeededForDisplay * itemSize.Width, containerSize.Height);
}
// Here scrolling is needed even after spreading in columns
int itemsPerColumn = (int)Math.Ceiling(wp1.Children.Count / (Double)iPossibleColumns);
return new Size(containerSize.Width, itemsPerColumn * itemSize.Height);
}