Search code examples
wpfwpf-controlsitemscontrol

WPF Items control doesnot show VerticalScrollBar automatically


Here is the intention,

When items get added to ItemsControl and if the content is more than the available size I wish to see scrolling in ItemsControl. I bet this is the default behavior for any ItemsControl type.

So I generated a sample replicates my intention. Suggest me what I need to fix

<StackPanel>
        <StackPanel.Resources>
            <Style TargetType="{x:Type ItemsControl}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ItemsControl}">
                            <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                <ScrollViewer VerticalScrollBarVisibility="Visible">
                                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </ScrollViewer>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>
        <ToggleButton Name="SomeToggle" Content="Show/Hide"/>
        <Button Content="Add Item" Click="ButtonBase_OnClick" />
        <TextBlock Text="Hide/Show on toggle" >
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Visibility" Value="Collapsed"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsChecked,ElementName=SomeToggle}" Value="True">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>

    <ItemsControl Name="ItemsCollection" >
    </ItemsControl>

</StackPanel>

and Code behind:

private int counter = 0;
    private ObservableCollection<string> coll; 
    public MainWindow()
    {
        coll= new ObservableCollection<string>();
        //ItemsCollection.ItemsSource = coll;
        InitializeComponent();
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        ItemsCollection.Items.Add(string.Format("Item {0}", ++counter));
    }

Solution

  • This is basically occurs each time you put a ScrollViewer inside a Stackpanel, and this is due to the way the Stackpanel works, take a look here

    you could either put the Stackpanel inside a ScrollView, or better change your main panel to a Grid

       <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>            
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.Resources>
            <Style TargetType="{x:Type ItemsControl}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ItemsControl}">
                            <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                <ScrollViewer VerticalScrollBarVisibility="Visible">
                                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </ScrollViewer>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <ToggleButton Name="SomeToggle" Content="Show/Hide" Grid.Row="0"/>
        <Button Content="Add Item" Click="ButtonBase_OnClick" Grid.Row="1"/>
        <TextBlock Text="Hide/Show on toggle" Grid.Row="2">
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Visibility" Value="Collapsed"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsChecked,ElementName=SomeToggle}" Value="True">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
        <ItemsControl Name="ItemsCollection" Grid.Row="3">
        </ItemsControl>
    </Grid>