I am currently working on my first WPF project and trying to make a ListView scrollable.
At first I thought this could be easily done by simply limiting the
This may help you..
private void ListViewScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
ScrollViewer scv = (ScrollViewer)sender;
scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
e.Handled = true;
}
In my case this helped:
<ScrollViewer ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Auto" >
<DataGrid x:Name="dataGrid" SelectionMode="Single" ItemsSource="{Binding}" SelectedValuePath="{Binding Item}" AutoGenerateColumns="True">
</DataGrid>
</ScrollViewer>
The design was disabling VerticalScrollBarVisibility attribute in outer scope , i.e. in ScrollViewer.
This would probably be the most comfortable solution:
<ListView.Template>
<ControlTemplate>
<ScrollViewer>
<ItemsPresenter></ItemsPresenter>
</ScrollViewer>
</ControlTemplate>
</ListView.Template>
For me this worked:
<ListView.Template>
<ControlTemplate>
<!-- Empty template to allow ScrollViewer to capture mouse scroll -->
<ItemsPresenter />
</ControlTemplate>
</ListView.Template>
instead of this:
<ListView.Template>
<ControlTemplate>
<ScrollViewer>
<ItemsPresenter></ItemsPresenter>
</ScrollViewer>
</ControlTemplate>
</ListView.Template>
<ScrollViewer Background="Transparent">
If Background is null, the mouse wheel will not work on ScrollViewer. You can set the Background to Transparent or some other value.
I want to add some comment to the solution Rocky provided. It worked fine for me, but later I needed to use it in a different window to scroll Grid. I faced a problem: the ScrollViewer did not scroll to the bottom end. The reason was because of attempts to set the invalid VerticalOffset value. The code below works fine for me (just need to change PreviewMouseWheel handler:
private void UIElement_OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
ScrollViewer scroll = (ScrollViewer)sender;
if (e.Delta < 0)
{
if (scroll.VerticalOffset - e.Delta <= scroll.ExtentHeight - scroll.ViewportHeight)
{
scroll.ScrollToVerticalOffset(scroll.VerticalOffset - e.Delta);
}
else
{
scroll.ScrollToBottom();
}
}
else
{
if (scroll.VerticalOffset + e.Delta > 0)
{
scroll.ScrollToVerticalOffset(scroll.VerticalOffset - e.Delta);
}
else
{
scroll.ScrollToTop();
}
}
e.Handled = true;
}