Search code examples
c#wpflistviewscroll

C# WPF ListView how to scroll on specific button press


I am implementing horizontal scroll into my ListView, it works but I need to scroll horizontally with mouse wheel.

I got so far that I know how to catch if the mouse wheel was scrolled up/down but I just need a command that will activate scroll left/right.

 private void UIElement_OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            ListView listView= (ListView)sender;
         
            if (e.Delta < 0)
            {
                // Scrolls right, I need here to activate event that will scroll right,
                // something like listView.ScrollRightByOneItem()
            }
            else
            {
               // Scrolls left, I need here to activate event that will scroll left,
               // something like listView.ScrollLeftByOneItem()
            }
            e.Handled = true;
        }

XAML

  <Grid>
        <ListView
            ItemsSource="{Binding Path=NotDeletedDevices}"
            MouseDoubleClick="ListView_MouseDoubleClick"
     PreviewMouseLeftButtonDown="ListView_PreviewMouseLeftButtonDown"
            PreviewMouseMove="ListView_PreviewMouseMove"
            SelectionMode="Single"
            PreviewMouseWheel="UIElement_OnPreviewMouseWheel"
            TouchDown="ListView_PreviewTouchDown"
            TouchMove="ListView_PreviewTouchMove">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>
  </Grid>

Is there any event that will let me scroll to the right or left by 1 item?

I need a command/event that will let me scroll to the right/left in the .xaml.cs file


Solution

  • I have defined a name to Listview lview (i think no need to define Scrollviewer, its automatically Auto i think)

        <ListView x:Name="lview" Grid.Column="0" Width="100" Height="100"
                  ScrollViewer.HorizontalScrollBarVisibility="Auto" 
                  ScrollViewer.VerticalScrollBarVisibility="Auto" 
                  PreviewMouseWheel="ListViewer_PreviewMouseWheel"/>
    

    As the scrollbar belongs to Listviewer, you have to find its instance so i define a method FindScrollViewer:

        private ScrollViewer FindScrollViewer(DependencyObject d)
        {
            if (d is ScrollViewer)
                return d as ScrollViewer;
    
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(d); i++)
            {
                var sw = FindScrollViewer(VisualTreeHelper.GetChild(d, i));
                if (sw != null) return sw;
            }
            return null;
        }
    
        private void ListViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
        {
            //find the scrollViewer instance of the control
            var scrollViewer = FindScrollViewer(lview);
    
            //get the horizontal value
            var h = scrollViewer.HorizontalOffset;
            // check the delta of wheel mouse >0 or <0
            var d = e.Delta;
            var nv = 0d;
            // are you at the beginning or end the scrolling
            if (d < 0)
            {
                nv = d + h < 0 ? 0 : d + h;
            }
            else
            {
                nv = d + h > scrollViewer.ScrollableWidth ? scrollViewer.ScrollableWidth : d + h;
            }
            // to block the vertical move
            scrollViewer.ScrollToVerticalOffset(0);
            //set the new horizontal position
            scrollViewer.ScrollToHorizontalOffset(nv);
        }
    

    i just show how to block the vertical move when you want to move the scrollbar horizontally.

    you can choose a keyboard (for example) to switch between horizontal/vertical