5

I am using ListView to display some items, let say of height 100. In case of many items, the Vertical scroll bar is displayed with ScrollViewer properties. However, when a user scrolls through the list, it is getting scrolled half of screen at times so with one scroll it covers the entire list view.

I want to have some code to set the amount of scroll, say 100 height at the time. I tried by searching through the doc but couldn't find anything. Actually, data comes from binding and number of items varies, but its fine to have some fixed height for each item.

Sample Code:

<ListView Name="lvSummaryList" ScrollViewer.VerticalScrollMode="Enabled"
                                              ScrollViewer.IsVerticalRailEnabled="True"
                                              VerticalAlignment="Bottom"
                                              SelectionMode="None"                                          ScrollViewer.VerticalScrollBarVisibility="Auto"   
                                              ScrollViewer.HorizontalScrollMode="Disabled"              ScrollViewer.IsVerticalScrollChainingEnabled="True"
                                              Margin="0,5,10,0"
                                              MaxHeight="600" >
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <ItemsWrapGrid Orientation="Horizontal" GroupPadding="1"  Margin="1" MinHeight="100" MaxHeight="200" MaximumRowsOrColumns="4" VerticalAlignment="Center"/>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
 </ListView>

How do I accomplish this, is there property or even available to override the current behavior?

wp78de
  • 18,207
  • 7
  • 43
  • 71
Chirag Rupani
  • 1,675
  • 1
  • 17
  • 37

2 Answers2

3

An easier way to achieve the effect it sounds like you're trying to achieve is to enable snap points on the ScrollViewer.

Use the following as the Style of your ListView:

        <Style TargetType="ListView"
               x:Key="SnapListViewStyle">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListView">
                        <Border BorderBrush="{TemplateBinding BorderBrush}"
                                Background="{TemplateBinding Background}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                            <ScrollViewer x:Name="ScrollViewer"
                                          TabNavigation="{TemplateBinding TabNavigation}"
                                          HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                          HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                          IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}"
                                          VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                          VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                          IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}"
                                          IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                          IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                          VerticalSnapPointsAlignment="Near"
                                          VerticalSnapPointsType="MandatorySingle"
                                          ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"
                                          IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                          BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
                                          AutomationProperties.AccessibilityView="Raw">
                                <ItemsPresenter Header="{TemplateBinding Header}"
                                                HeaderTemplate="{TemplateBinding HeaderTemplate}"
                                                HeaderTransitions="{TemplateBinding HeaderTransitions}"
                                                Footer="{TemplateBinding Footer}"
                                                FooterTemplate="{TemplateBinding FooterTemplate}"
                                                FooterTransitions="{TemplateBinding FooterTransitions}"
                                                Padding="{TemplateBinding Padding}" />
                            </ScrollViewer>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

If that doesn't give the effect you're going for, try different values for VerticalSnapPointsType and VerticalSnapPointsAlignment.

David Oliver
  • 2,251
  • 12
  • 12
0

You can try to set the SmallChange property or you can listen to the Scroll event of the vertical ScrollBar, and pragmatically adjust the ScrollBar position as needed.

PS: There are other ways to get a reference to the scrollviewer of the ListView as the one shown.

    public MainPage()
    {
        this.InitializeComponent();

        var scrollViewer = GetDescendants(lvSummaryList).OfType<ScrollViewer>().FirstOrDefault();
        var verticalScrollbar = GetDescendants(scrollViewer).OfType<ScrollBar>()
            .FirstOrDefault(x => x.Orientation == Orientation.Vertical);

        verticalScrollbar.SmallChange = 5;

        //You can listen to the Scroll event of the vertical ScrollBar, and to pragmatically adjust the ScrollBar position
        /*verticalScrollbar.Scroll += (o, e) =>
        {
            if (e.ScrollEventType != ScrollEventType.EndScroll)
                scrollViewer.ScrollToVerticalOffset(100); // Scroll to the top

            if (e.NewValue >= verticalScrollbar.Maximum)
                scrollViewer.ScrollToVerticalOffset(0); // Scroll to the top
        };*/
    }

    public static IEnumerable<DependencyObject> GetDescendants(DependencyObject start)
    {
        var queue = new Queue<DependencyObject>();
        var count = VisualTreeHelper.GetChildrenCount(start);

        for (int i = 0; i < count; i++)
        {
            var child = VisualTreeHelper.GetChild(start, i);
            yield return child;
            queue.Enqueue(child);
        }

        while (queue.Count > 0)
        {
            var parent = queue.Dequeue();
            var count2 = VisualTreeHelper.GetChildrenCount(parent);

            for (int i = 0; i < count2; i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                yield return child;
                queue.Enqueue(child);
            }
        }
    }
wp78de
  • 18,207
  • 7
  • 43
  • 71
  • 1
    I am getting null value for scrollViewer in `var scrollViewer = GetDescendants(lvSummaryList).OfType().FirstOrDefault();` – Chirag Rupani Aug 20 '17 at 07:53
  • Do it in the Loaded event – Justin XL Aug 20 '17 at 09:33
  • 1
    Got it, it works once item source is set. This is very helpful to get scroll viewer programmatically and small change works, but other answer help me to get smooth scroll especially to avoid bouncing at very end of scroll, so marking it as accepted. – Chirag Rupani Aug 23 '17 at 02:05