Click here to Skip to main content
15,892,737 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello guys,
please do you have idea how could i add ScrollViewer to used StackPanel? But it must work :-)
It announces me an InvalidOperationException anyhow i try to add ScrollViewer into View XAML.

Here is a original question what i want to do. I only need to add scroll bar:
WPF/MVVM - binding collection of child controls - Stack Overflow[^]

I am loading Shippers collection, code will create dynamicly one button for each collection member. I use Shipper property BtnLabel as button text.
My whole XAML View:

<Window x:Class="EnterEventTextBox.DataView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:EnterEventTextBox"
        mc:Ignorable="d" Background="Black"
        Title="DataView" Height="450" Width="800"
        xmlns:cal="http://www.caliburnproject.org"
        >
    <StackPanel>
        <ItemsControl ItemsSource="{Binding Shippers}" Height="100" Width="300" Margin="80,70,412,249">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal"></WrapPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type Button}">
                    <StackPanel>
                        <Button Background="Red" Content="{Binding Path=BtnLabel}" Margin="0,0,5,5"></Button>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</Window>


What I have tried:

Add scrolling to different tags. Reorganize this code in order it allow me to add ScrollViewer there.
Posted
Updated 11-Aug-18 7:20am
v14
Comments
Graeme_Grant 10-Aug-18 13:30pm    
You don't. You wrap the ItemsControl instead.
Member 13944101 10-Aug-18 17:39pm    
Any idea how to add scrollBar to the mentioned code above is welcome.

 
Share this answer
 
Comments
Member 13944101 10-Aug-18 17:37pm    
No, i have seen this link many times, but this was exactly what i wrote about.
When i try to add <scrollviewer> anywhere, it will fire up mentioned Exception. I have even tried some StackPanel's embedded properties related to scrolling (for example CanHorizontallyScroll) but without success.
To help understand the problem, here are the default templates (extracted using MS Blend) of the ItemsControl:
XML
<ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
    <StackPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
<Style x:Key="ItemsControlStyle1" TargetType="{x:Type ItemsControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ItemsControl}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The ItemsPanel must be a container control. By putting the StackPanel inside a ScrollViewer, the ItemsControl is attempting to put the ItemsPresenter content iside the ScrollViewer Content. The error that you are seeing is that more than one control is inside the ScrollViewer content where their is already a StackPanel - invalid.

So, to fix, you have two options:

1. Wrap the ItemsControl inside a ScrollViewer control:
XML
<ScrollViewer>
    <ItemsControl Name="ic1" Height="60" Width="300" Margin="80,70,412,249">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type Button}">
                <Button Background="Red" Content="{Binding}" Margin="0,0,5,5"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <system:String>Item #1</system:String>
        <system:String>Item #2</system:String>
        <system:String>Item #3</system:String>
        <system:String>Item #4</system:String>
        <system:String>Item #5</system:String>
    </ItemsControl>
</ScrollViewer>

** This is the solution that I mentioned earlier above.

2. Wrap the ItemsPresenter in the ItemsControl Style (body):
XML
<Window.Resources>
    <ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
        <StackPanel IsItemsHost="True"/>
    </ItemsPanelTemplate>
    <Style x:Key="ItemsControlStyle1" TargetType="{x:Type ItemsControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ItemsControl}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                        <ScrollViewer VerticalScrollBarVisibility="Auto">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid>
    <ItemsControl ItemsPanel="{DynamicResource ItemsPanelTemplate1}" Style="{DynamicResource ItemsControlStyle1}">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type Button}">
                <Button Background="Red" Content="{Binding}" Margin="0,0,5,5"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <system:String>Item #1</system:String>
        <system:String>Item #2</system:String>
        <system:String>Item #3</system:String>
        <system:String>Item #4</system:String>
        <system:String>Item #5</system:String>
    </ItemsControl>
</Grid>

Note: I have removed the fixed height from the StackPanel Control in the ItemsPanelTemplate - if not done, it will cause layout and debugging issues later on.
 
Share this answer
 
Comments
Member 13944101 11-Aug-18 15:23pm    
Excellent! Second version works :-) First i havent tried but i am happy, thanks a lot bro :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900