0

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));
    }
WPFKK
  • 1,419
  • 3
  • 20
  • 42

2 Answers2

2

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>
Community
  • 1
  • 1
SamTh3D3v
  • 9,854
  • 3
  • 31
  • 47
  • @Sam if any row of grid will ever get bigger than grid's container(say window here), then we may have some issues here. – Kylo Ren Feb 08 '16 at 06:17
0

The only reason you are not able to see the scrollbars cause you have not set the height of your ItemsControl.

Every time you add a item it's height will expand and StackPanel will expand with it to contain the content. You have already defined ScrollViewer to your ItemsControl template you have to also decide at what point it has to work.

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

Then it will also not matter either you containing it in a StackPanel or any other control.

initial scroll bar initial scroll bar

After adding items After adding items

with code with code

And just from understanding point of view. this will also work:

Remove style for item control & set the height of scroll viewer. enter image description here

To handle the height of all elements:

<ScrollViewer MaxHeight="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}},Path=ActualHeight,Mode=OneWay}">
    <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="Button_Click" />
    <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" ItemsSource="{Binding list}" 
                  MaxHeight="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}},Path=ActualHeight,Mode=OneWay}">
    </ItemsControl>

</StackPanel>
</ScrollViewer>
Kylo Ren
  • 8,551
  • 6
  • 41
  • 66
  • It wont work that way. It has to be enclosed in a grid only then it is working. – WPFKK Jan 25 '16 at 20:28
  • @user841612 why not you think? please see updated answer with screen shots. – Kylo Ren Jan 26 '16 at 05:23
  • the scenario u posted: when window size is small to fit only content and i show or hide items dynamically the scroll bar shifts below. Since you have a fixed height – WPFKK Feb 01 '16 at 12:36
  • @user841612 ok. :) actually the question was about item's control scroll bar, so didn't do the adjustment for others. And I'm sure Grid is not your answer as well(it is working while the textbox element is of small size ). try to increase height of textbox(show/hide one) and see. If you truly want to achieve this then you have to put scrollviewer outside the content of window in my code. – Kylo Ren Feb 07 '16 at 15:54
  • @user841612 As soon as the height of textbox increases the height of grid, you see the your item's control is not visible completely. Not just with the grid it will happen with every control that can have some content but doesn't have a scroll viewer to show the whole content like grid, Stackpanel, ContentControl or Window. – Kylo Ren Feb 07 '16 at 16:11