あなたが求めていることを実際に行うことは可能ですが、かなりの量のカスタムコードが必要になります。
通常、WPFでは、ScrollViewerは論理スクロールと呼ばれるものを使用します。これは、オフセット量ではなくアイテム単位でスクロールすることを意味します。その他の答えは、論理スクロールの動作を物理スクロールの動作に変更できるいくつかの方法をカバーしています。もう1つの方法は、ScrollViwerとIScrollInfoの両方で公開されるScrollToVertialOffsetメソッドとScrollToHorizontalOffsetメソッドを使用することです。
大きな部分を実装するには、マウスホイールを押したときにスクロールして、MouseDownおよびMouseMoveイベントを使用する必要があります。 MouseDownで
<ListView x:Name="uiListView"
Mouse.MouseDown="OnListViewMouseDown"
Mouse.MouseMove="OnListViewMouseMove"
ScrollViewer.CanContentScroll="False">
....
</ListView>
、我々は我々がスクロールどの方向を決定するために相対的な点として使用する現在のマウス位置を記録しようとしている。マウスの動きで、我々はScrollViwer成分を得ようとしていますそれに応じてスクロールします。
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または類似のものに入れることができます。
ありがとうございます。仮想化とは何ですか? –
VirtualizationStackPanel(ListBoxなどのデフォルトのItemsPanel)内のコンテンツは、アイテムが表示されるまで/実際にアイテムのレイアウトをレンダリングしません。したがって、多数の視覚的に複雑なアイテムでは、一度にわずかなパーセンテージでしかUIを生成しないため、大幅なパフォーマンスの向上を実現できます。 詳細情報: http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.aspx – rmoore
これは、論理的なスクロールから物理的なスクロールに切り替えることです(あなたが実装しているStackPanelを使用していると仮定します)。 IScrollInfo)。論理スクロールをしたいがスムーズにしたい場合は、これは役に立ちません – Schneider