1

I have an ItemControl on a ScrollViewer. I want to scroll item by item, now is scrolling pixel by pixel.

<ScrollViewer Height="299" Margin="10,10,0,0" 
HorizontalScrollBarVisibility="Visible" x:Name="Scroll"
                  VerticalAlignment="Top"  
                  Grid.Column="0" Grid.Row="1" 
                  PanningMode="HorizontalOnly" 
                  CanContentScroll="True">
        <ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Items, Mode=OneWay}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border  Width="175" Height="64" Margin="0,0,16,16" HorizontalAlignment="Center" Focusable="False">
                        <TextBlock Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
nvoigt
  • 75,013
  • 26
  • 93
  • 142
Nicu Besliu
  • 453
  • 5
  • 17

3 Answers3

1

Just set this property on ListBox:

VirtualizingStackPanel.ScrollUnit ="Item"

Another mode is "Pixel", which is default mode.

Parag
  • 543
  • 1
  • 8
  • 18
1

I found a solution

<ItemsControl ItemsSource="{Binding TypeHeaders}" 
                                      x:Name="ActivityItemsControl" 
                                      Grid.Column="0" Grid.Row="1">
                            <ItemsControl.Template>
                                <ControlTemplate>
                                    <ScrollViewer HorizontalScrollBarVisibility="Hidden" 
                                                  VerticalScrollBarVisibility="Visible" 
                                                  CanContentScroll="True"                                                       
                                                  x:Name="ActivityScrollViewer">
                                        <ItemsPresenter/>
                                        <i:Interaction.Triggers>
                                            <i:EventTrigger EventName="ScrollChanged">
                                                <cmd:EventToCommand PassEventArgsToCommand="True" 
                                                        Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Grid}}, Path=DataContext.VmCommands.ActivityScrollChangedCommand}" />
                                            </i:EventTrigger>
                                        </i:Interaction.Triggers>
                                    </ScrollViewer>
                                </ControlTemplate>
                            </ItemsControl.Template>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Button Content="{Binding Description}" Style="{DynamicResource ZoneTypeHeaderButtonStyle}"
                                                        Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Path=DataContext.VmCommands.ZoneOverviewControlTypeHeaderClickedCommand}"
                                                        CommandParameter="{Binding}"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
Nicu Besliu
  • 453
  • 5
  • 17
0

You can use ListBox instead of ScrollViewer. I thought you did not want to have a selection style so I changed it.

    <ListView ScrollViewer.CanContentScroll="True" 
              ScrollViewer.VerticalScrollBarVisibility="Hidden"
              ScrollViewer.PanningMode="HorizontalOnly"
              ScrollViewer.HorizontalScrollBarVisibility="Visible"
              ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Items, Mode=OneWay}">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <Setter Property="Background" Value="Transparent" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListViewItem}">
                            <ContentPresenter />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Border Width="175" Height="64" Margin="0,0,16,16" HorizontalAlignment="Center" Focusable="False">
                    <TextBlock Text="{Binding }" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
cptiv
  • 167
  • 1
  • 6
  • Thanks @Jarosław Rejterada, but i need to catch scroll events from scroll viewer and change ScrollingOffset from code. Also i want to use event to command from mvvm light. – Nicu Besliu May 11 '17 at 06:34
  • It's still possible, you can edit template for list view and there you have full access to scrollviewer. (for generate base template Right click on control in designer -> EditTemplate -> Edit copy). Or see http://stackoverflow.com/questions/1585462/bubbling-scroll-events-from-a-listview-to-its-parent – cptiv May 11 '17 at 07:33