Действительно возможно сделать то, что вы просите, хотя это потребует значительного количества пользовательского кода.
Обычно в WPF ScrollViewer использует так называемую логическую прокрутку, что означает, что он будет прокручивать элемент за элементом, а не на величину смещения. Другие ответы охватывают некоторые способы, которыми вы можете изменить поведение логической прокрутки на поведение физической прокрутки. Другой способ заключается в использовании методов ScrollToVertialOffset и ScrollToHorizontOffset, предоставляемых как ScrollViwer, так и IScrollInfo.
Чтобы реализовать большую часть, прокрутку при нажатии колеса мыши, нам нужно будет использовать события MouseDown и MouseMove.
<ListView x:Name="uiListView"
Mouse.MouseDown="OnListViewMouseDown"
Mouse.MouseMove="OnListViewMouseMove"
ScrollViewer.CanContentScroll="False">
....
</ListView>
В MouseDown мы собираемся записать текущую позицию мыши, которую мы будем использовать в качестве относительной точки, чтобы определить направление прокрутки. При движении мыши мы получим компонент ScrollViwer объекта ListView и затем прокрутите его соответственно.
private Point myMousePlacementPoint;
private void OnListViewMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.MiddleButton == MouseButtonState.Pressed)
{
myMousePlacementPoint = this.PointToScreen(Mouse.GetPosition(this));
}
}
private void OnListViewMouseMove(object sender, MouseEventArgs e)
{
ScrollViewer scrollViewer = ScrollHelper.GetScrollViewer(uiListView) as ScrollViewer;
if (e.MiddleButton == MouseButtonState.Pressed)
{
var currentPoint = this.PointToScreen(Mouse.GetPosition(this));
if (currentPoint.Y < myMousePlacementPoint.Y)
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - 3);
}
else if (currentPoint.Y > myMousePlacementPoint.Y)
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + 3);
}
if (currentPoint.X < myMousePlacementPoint.X)
{
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - 3);
}
else if (currentPoint.X > myMousePlacementPoint.X)
{
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + 3);
}
}
}
public static DependencyObject GetScrollViewer(DependencyObject o)
{
// Return the DependencyObject if it is a ScrollViewer
if (o is ScrollViewer)
{ return o; }
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
{
var child = VisualTreeHelper.GetChild(o, i);
var result = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}
Есть некоторые области, которых ему не хватает, так как это просто доказательство концепции, но это определенно должно привести вас в правильном направлении. Чтобы она постоянно прокручивалась после перемещения мыши от начальной точки MouseDown, логика прокрутки может переходить в DispatcherTimer или что-то подобное.