I have this:
<Window x:Class="ScrollTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="450"
Width="525">
<ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0"
Header="Stuff"
Height="200">
<TextBlock Text="Lots of controls go here"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</GroupBox>
<TabControl Grid.Row="1">
<TabItem Header="Main Tab">
<TextBox MinHeight="100"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Top"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
AcceptsReturn="True" />
</TabItem>
</TabControl>
</Grid>
</ScrollViewer>
</Window>
When I add too many rows into the TextBox, instead of the ScrollViewer of the TextBox being used, the box stretches and the outermost ScrollViewer is used. Can I prevent that without fixing the height of the TextBox or TabControl?
Update:
If I remove MinHeight on the TextBox and set MaxLines to 5, this is what I get:
If I added a 6th line, the scroll bars of the TextBox's ScrollViewer are used, but they still remain centered vertically in the TextBox control.
I was able to get close with this:
<Window x:Class="ScrollTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525">
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Visible"
x:Name="Base">
<Grid Height="{Binding ElementName=Base, Path=ActualHeight, Mode=OneWay}"
MinHeight="400">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0"
Header="Stuff"
Height="200">
<TextBlock Text="Lots of controls go here"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</GroupBox>
<TabControl Grid.Row="1">
<TabItem Header="Main Tab">
<Grid x:Name="myInnerGrid">
<TextBox MinHeight="100"
MaxHeight="{Binding ElementName=myInnerGrid, Path=ActualHeight, Mode=OneWay}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Top"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
AcceptsReturn="True" />
</Grid>
</TabItem>
</TabControl>
</Grid>
</ScrollViewer>
</Window>
Note the binding expression on height for the outside grid and on MaxHeight for the TextBox.
It's still not perfect in that you have to manually set the MinHeight that will trigger the outer most scrollbar. It's probably as close as WPF will allow without writing a new grid control.
The idea was found here:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/7b4b0c88-6b8f-4f07-aa8b-8e7018762388
Try looking at the MaxLines and MinLines Properties.
From above link:
Setting this property causes the text box to resize if the number of
visible lines exceeds the limit specified by MaxLines. This property
applies only to visible lines, and does not constrain the actual
number of lines. Depending on its configuration, a text box may
contain additional non-visible lines that are accessible by scrolling.
If the Height property is explicitly set on a TextBox, the MaxLines
and MinLines property values are ignored.
Try Changing:
<TextBox MinHeight="100"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
...
to
<TextBox MinLines="5"
MaxLines="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Edit: Give this a try. It is setting the VerticalContentAlignment of the TabItem. This will keep the text box at the top of the Tab, I also set the maxlines to what your available area is able to hold if you resize your form you may want to adjust that number to use all of the available space.
<TabItem Header="Main Tab" VerticalContentAlignment="Top" >
<TextBox
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
MinLines="8"
MaxLines="8"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
AcceptsReturn="True" />
</TabItem>
Edit:
After looking into it further, the reason the scrollbars are not showing up on the TextBox is because the TabControl and the TabItem are resizing to the size of the TextBox. What needs to be done is to have a limiting height set either on the TabControl, TabItem or TextBox this will allow the ScrollViewer to work for the TextBox.
I found that the best solution to this is to use the Border trick outlined here, applied both vertically and horizontally.
In the following example, a ScrollViewer contains a TextBox, where it is desired to have the TextBox fit all of the available space (vertically and horizontally), and have it scroll vertically before the parent ScrollViewer. The Border PlaceHolderBorder manages the Width of the TextBoxes as the parent window is resized. The Border DescriptionPlaceHolderBorder manages the Height of the Description TextBox as the parent control is resized, and the ScrollViewer of the TextBox kicks in before the parent control.
It is important to have Margins in the placeholder Borders.
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Background="{StaticResource ControlBackgroundBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Style="{DynamicResource LabelHeader}" Content="Company" />
<Label Grid.Row="1" Grid.Column="1" Style="{DynamicResource CompanyNameInput}" Content="{Binding CompanyNameLabel}" />
<Label Grid.Row="2" Grid.Column="1" Style="{DynamicResource DescriptionInput}" Content="{Binding DescriptionLabel}" />
<Border Name="PlaceHolderBorder" Grid.Column="2" Margin="7"/>
<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding CompanyName}" MaxLength="255"/>
<Border Name="DescriptionPlaceHolderBorder" Grid.Row="2" Margin="7"/>
<TextBox Grid.Row="2" Grid.Column="2" Text="{Binding Description}" VerticalScrollBarVisibility="Auto"
TextAlignment="Left" TextWrapping="Wrap" AcceptsReturn="True" MinHeight="60"
Width="{Binding ElementName=PlaceHolderBorder, Path=ActualWidth}"
Height="{Binding ElementName=DescriptionPlaceHolderBorder, Path=ActualHeight}"
/>
<StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="2" Margin="5">
<Button Command="{Binding UpdateCommand}" Content="{Binding UpdateButtonLabel}"></Button>
<Button Command="{Binding ResetCommand}" Content="{Binding ResetButtonLabel}"></Button>
<Button Command="{Binding CloseConfirmCommand}" Content="{Binding CloseButtonLabel}"></Button>
</StackPanel>
</Grid>
</ScrollViewer>
Related
I'm trying to hide a column in a Grid with a GridSplitter when a button is clicked (the button sets the visibility of all items in the third column to collapsed). If I don't move the GridSplitter it works properly and the third column disappear, but if I move the GridSplitter the content disappear but the others columns don't resize to fill the empty space.
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="a" Width="*"/>
<ColumnDefinition x:Name="b" Width="3"/>
<ColumnDefinition x:Name="c" Width="Auto" MaxWidth="600"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" Background="Green">
<Image Source="te/Dante.png" Height="Auto" Margin="0,128,2,71"/>
</Border>
<Button Grid.Column="0" Grid.Row="0" Width="30" Height="30" Margin="0,10,10,0" HorizontalAlignment="Right" VerticalAlignment="Top" Click="Button_Click"></Button>
<GridSplitter Width="5" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" ResizeDirection="Columns" HorizontalAlignment="Left" Background="White" BorderBrush="Black" BorderThickness="1,0" ResizeBehavior="PreviousAndCurrent"/>
<WrapPanel x:Name="wpC" Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" MinWidth="300" HorizontalAlignment="Stretch" Background="Aqua" Panel.ZIndex="-1"></WrapPanel>
</Grid>
Here is an example of my problem (gif):
How can i solve this problem? Possibly respecting MVVM pattern.
The problem is simple, you set GridSplitter ResizeBehavior="PreviousAndCurrent", but previous grid column width is * and as soon as you move splitter its width units will be changed to absolute (so it will not be able to resize when 3d column width is changed).
Simply set GridSplitter ResizeBehavior="PreviousAndNext" to solve the problem. If you do so the splitter will modify width of 3d column, but shouldn't touch first one anymore.
Btw, instead of using button and click event you can utilize ToggleButton (which IsChecked is bound to Visibility of container with content you want to hide), see this answer. Using converters with pure xaml view is better MVVM than the one with some code behind and x:Name.
Right, you have few layout problems, here is a complete solution:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Background="Green" />
<ToggleButton x:Name="toggleButton"
Width="30"
Height="30"
Margin="0,10,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Top" />
<Grid Grid.Column="1"
Visibility="{Binding IsChecked, ElementName=toggleButton, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="300"
MinWidth="300"
MaxWidth="600" />
</Grid.ColumnDefinitions>
<GridSplitter Width="5"
ResizeBehavior="CurrentAndNext" />
<WrapPanel Grid.Column="1"
Background="Aqua" />
</Grid>
</Grid>
No need for code-behind, get converter from here.
Point are: 1) put splitter inside hide-able container 2) setup grid columns to have * and fixed width (splitter doesn't work well with auto columns).
Demo:
So I am having some trouble getting the binding of a lisbox height to work. I have a user control that holds a listbox, this box is dynamically populated on the fly but it seems that if too many items are added it extends past the boundaries of the parent objects and refuses to stop and use the scoll bar...
<UserControl x:Class="TransaltionModule.Views.NoteView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<Grid>
<ListBox ItemsSource="{Binding noteList}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0">
<TextBlock Text="Type :" VerticalAlignment="Center" FontSize="14" Width="65"/>
<TextBox Text="{Binding noteType}" Width="auto" IsEnabled="False" VerticalAlignment="Center" FontSize="14"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Right">
<TextBlock Text="Date :" VerticalAlignment="Center" FontSize="14" Width="65"/>
<TextBox Text="{Binding timeStamp}" Width="auto" IsEnabled="False" VerticalAlignment="Center" FontSize="14"/>
</StackPanel>
<TextBlock Grid.Row="1" Text="{Binding text}" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
If i hardcode the maxheight property everything works as intended, but with the multiple display resolutions I will be working against that is not a solution I can use. Can anyone recommend a fix
You can bind it to an element by using Path=ActualHeight
For this to work don't forget to name the Grid containing the Listbox
Try something like this :
<Grid x:Name = "grdListBoxTest">
<ListBox x:Name="lstBoxTest"
MaxHeight="{Binding ElementName=grdListBoxTest, Path=ActualHeight}">
<!-- Your Listbox Stuff Here -->
</ListBox>
</Grid>
By doing this you link the height of the Listbox to it's parent Grid. That way if the grid's size changes the MaxHeight of the Listbox will change.
I am using ExpanderView from Toolkit for Windows Phone. What I add is line below each Header. What I can't do is stretch line for Headers which are Expandable.
<toolkit:ExpanderView x:Name="ev" HorizontalAlignment="Stretch" Margin="0,0,0,8"
Header="{Binding}"
NonExpandableHeader="{Binding}"
Expander="{Binding}"
ItemsSource="{Binding}"
IsNonExpandable="{Binding HasSingleMessage}">
<toolkit:ExpanderView.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding LastMessageReceived.Header}"
HorizontalAlignment="Stretch"
Foreground="Black"
FontSize="{StaticResource PhoneFontSizeLarge}"
FontFamily="{StaticResource PhoneFontFamilySemiLight}"/>
<Rectangle Height="1" StrokeThickness="0" Fill="Black" Margin="0,8" />
</StackPanel>
</DataTemplate>
</toolkit:ExpanderView.HeaderTemplate>
It's a bit tricky to get to the bottom of this. The bottom line is, I think the only way get what you want (stretch the line) is to include a modified version of the control template in your XAML resources, and make the header stretch to fill its container.
If you check source code at the link, and scroll down to the ExpanderView control template, you will see that the header element is defined like this:
<ListBoxItem x:Name="ExpandableContent" controls:TiltEffect.IsTiltEnabled="True"
Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="41"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ContentControl x:Name="Header"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Grid.Row="0" Grid.Column="0"
Grid.ColumnSpan="2"/>
<ContentControl x:Name="Expander"
Margin="11,0,0,0"
Grid.Row="1" Grid.Column="1"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
Content="{TemplateBinding Expander}"
ContentTemplate="{TemplateBinding ExpanderTemplate}"/>
<Grid x:Name="ExpanderPanel" Grid.Row="0" Grid.Column="0"
Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Transparent"/>
</Grid>
</ListBoxItem>
Now, at first glance this looks fine, because the "Header" ContentControl has both HorizontalAlignment and HorizontalContentAlignment set to "Stretch". Unfortunately, the parent ListBoxItem does not define its HorizontalContentAlignment, whose default may not be "Stretch". (I'm uncertain on this point because the MSDN documentation does not list the default -- but the default for the corresponding property is "Left" in WPF and "Center" in Silverlight.)
So I would try copying the default control template into your application resources, and add the appropriate alignments to the "ExpandableContent" ListBoxItem:
<ListBoxItem x:Name="ExpandableContent"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" ...
There are a few aesthetic problems with my GUI that I can't quite figure out. The first one is my mouse over. I have a TextBlock with a MouseUp Event attached to it and I want the cursor to change to a hand when I mouse over so in the xaml I used Cursor="Hand" as shown below
<TextBlock Grid.Row="1" x:Name="AttachFileTextBlock" Foreground="Blue"
HorizontalAlignment="Right" FontSize="16" MouseUp="AttachFileTextBlock_MouseUp"
Cursor="Hand">
<Underline>Attach Screen Shots</Underline>
</TextBlock>
However the hand only appears around the edges and furthermore the actual text is not clickable, only clicking the edges trigger the mouse up event.
My other problem is in my UserControl, a HorizontalScrollBar is appearing even though I clearly set HorizontalScrollBarVisibility="Disabled" in my ScrollViewer
Here is the complete xaml
<UserControl x:Class="Client.App.Support.ListOfScreenShots"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="520" d:DesignWidth="800">
<Grid>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ListBox Name="_listBox" ItemsSource="{Binding ''}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="550"/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<Image Name="_image" Grid.Column="0" Height="400" Width="550" HorizontalAlignment="Center" VerticalAlignment ="Center" Stretch="Uniform" Source="{Binding ''}"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Bottom" Name="_addscreenshot" Content="Select Screenshot"
Height="30" Width="150" Margin="3.5,0,3.5,7"/>
<Button Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Top" Name="_removescreenshot" Content="Remove Screenshot"
Height="30" Width="150" Margin="3.5,0,3.5,7"/>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
I am just starting to learn WPF in depth and I really really hate it right now. If this is supposed to be an improvement on other methods of creating UIs I can't even imagine what its predecessors were like. Hopefully it will all click some day.
I am adding a ScrollViewer to ItemsControl whose ItemTemplate is generated dynamically.
The problem is the ScrollViewersnaps back to its initial position after scrolling. I tried setting the grid container Grid.Row="1" in which the ScrollViewer lies so that it has enough height or set it auto but the problem persist. What am I missing?
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding GameLevel, Converter={StaticResource EnumToStringConverter}}" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock HorizontalAlignment="Right" Grid.Column="1" Style="{StaticResource PhoneTextNormalStyle}">
<Run Text="GAME "/>
<Run Text="{Binding CurrentGame}"/>
<Run Text=" / "/>
<Run Text="{Binding TotalGame}"/>
</TextBlock>
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle2Style}">
<Run Text="{Binding CurrentTime, Converter={StaticResource SecondsToMinutesHour}}"/>
</TextBlock>
<TextBlock Foreground="Green" HorizontalAlignment="Right" Grid.Column="1" Margin="9,-7,9,0" Style="{StaticResource PhoneTextTitle2Style}">
<Run Text="{Binding TotalTime, Converter={StaticResource SecondsToMinutesHour}}"/>
</TextBlock>
<ProgressBar Grid.Row="1" Grid.ColumnSpan="2" x:Name="ProgressBar" Value="{Binding ProgressBarTime}" Minimum="0" Maximum="100" VerticalAlignment="Top" CacheMode="BitmapCache"/>
</Grid>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer>
<ItemsControl x:Name="itemsControl" ItemsSource="{Binding Tiles}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Tag="{Binding Index}" Loaded="FrameworkElement_OnLoaded">
<Button Width="{Binding Side}"
Height="{Binding Side}"
Background="{Binding BgColor}"
Tag="{Binding Index}"
Content="{Binding Index}"
FontSize="{StaticResource PhoneFontSizeSmall}"
Click="Button_Click">
<ia:Interaction.Triggers>
<ia:EventTrigger EventName="Loaded">
<tr:SetCanvasPropertiesAction Left="{Binding Left}" Top="{Binding Top}" />
</ia:EventTrigger>
</ia:Interaction.Triggers>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
<Grid x:Name="adGrid" Grid.Row="2" HorizontalAlignment="Center"/>
</Grid>
edit:
Ok, the real problem is, that the ItemsPnaelTemplate is a Canvas. The canvas always has Height=0 and Width=0. Items that are placed in the canvas can be bigger, but are still inside the canvas. The scrollviewer only has the Height of the canvas as an idea on how much it should be able to scroll.
You can easily test this by temporarily setting the height of the canvas:
<ItemsPanelTemplate>
<Canvas Height="1500"/>
</ItemsPanelTemplate>
And you will see, that now you can scroll.
Unfortunately I can't think of a solution right now. (Maybe setting the width and height of the itemsControl through code behind by calculating the needed width and height to dispay all items, by taking the items with the highest value for (Top + Side) as Height and (Left + Side) for Width)
original:
Your ContentPanel Grid has this Height="Auto". So the ContentPanel is the same Height as the ScrollViewer and all of it's content and the actual scrolling that you can still do is just the bouncing effect of the ScrollViewer when you get to the end of it's scrolling ability.
Just delete Height="Auto" and you should be fine.