是否可以更改WPF ScrollViewer滚动的数量?我只是想知道是否可以更改滚动查看器,以便在使用鼠标滚轮或滚动查看器箭头时,可以更改增量滚动的数量。

有帮助吗?

解决方案

简短的回答是:没有编写一些自定义滚动代码就没有办法做到这一点,但不要让你吓唬它并不是那么难。

ScrollViewer通过使用物理单位(即像素)滚动或通过与IScrollInfo实现交互来使用逻辑单元。这是通过设置 CanContentScroll属性

其中值false表示“使用物理单位滚动内容”。并且值为true意味着“逻辑地滚动内容”。

那么ScrollViewer如何在逻辑上滚动内容?通过与IScrollInfo实现进行通信。因此,当有人执行逻辑操作时,您可以准确地接管面板内容滚动的程度。 查看IScrollInfo的文档获取可以请求滚动的所有测量逻辑单元的列表,但是由于您提到了鼠标滚轮,因此您将最感兴趣的是MouseWheelUp / Down / Left / Right方法。

其他提示

这是一个简单,完整且有效的 WPF ScrollViewer 类,它具有数据绑定 SpeedFactor 属性,用于调整鼠标滚轮灵敏度。将 SpeedFactor 设置为1.0意味着与WPF ScrollViewer 的行为相同。依赖项属性的默认值为 2.5 ,这样可以非常快速地滚动滚轮。

当然,您还可以通过绑定到 SpeedFactor 属性本身来创建其他有用的功能,即轻松允许用户控制乘数。

public class WheelSpeedScrollViewer : ScrollViewer
{
    public static readonly DependencyProperty SpeedFactorProperty =
        DependencyProperty.Register(nameof(SpeedFactor),
                                    typeof(Double),
                                    typeof(WheelSpeedScrollViewer),
                                    new PropertyMetadata(2.5));

    public Double SpeedFactor
    {
        get { return (Double)GetValue(SpeedFactorProperty); }
        set { SetValue(SpeedFactorProperty, value); }
    }

    protected override void OnPreviewMouseWheel(MouseWheelEventArgs e)
    {
        if (!e.Handled && 
            ScrollInfo is ScrollContentPresenter scp &&
            ComputedVerticalScrollBarVisibility == Visibility.Visible)
        {
            scp.SetVerticalOffset(VerticalOffset - e.Delta * SpeedFactor);
            e.Handled = true;
        }
    }
};

完成大约3200个数据项的“快速鼠标滚轮滚动”的XAML演示:

<UserControl x:Class="RemoveDuplicateTextLines.FastScrollDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyApp"
    xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <local:WheelSpeedScrollViewer VerticalScrollBarVisibility="Auto">
        <ListBox ItemsSource="{Binding Source={x:Type sys:Object},Path=Assembly.DefinedTypes}" />
    </local:WheelSpeedScrollViewer>

</UserControl>

快速鼠标滚轮:

您可以在scrollviewer上实现一种行为。在我的情况下, CanContentScroll 不起作用。下面的解决方案适用于使用鼠标滚轮滚动以及拖动滚动条。

public class StepSizeBehavior : Behavior<ScrollViewer>
{
    public int StepSize { get; set; }

    #region Attach & Detach
    protected override void OnAttached()
    {
        CheckHeightModulesStepSize();
        AssociatedObject.ScrollChanged += AssociatedObject_ScrollChanged;
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.ScrollChanged -= AssociatedObject_ScrollChanged;
        base.OnDetaching();
    }
    #endregion

    [Conditional("DEBUG")]
    private void CheckHeightModulesStepSize()
    {
        var height = AssociatedObject.Height;
        var remainder = height%StepSize;
        if (remainder > 0)
        {
            throw new ArgumentException(
<ScrollViewer MaxHeight="248"
              VerticalScrollBarVisibility="Auto">
    <i:Interaction.Behaviors>
        <behaviors:StepSizeBehavior StepSize="62" />
    </i:Interaction.Behaviors>
quot;{nameof(StepSize)} should be set to a value by which the height van be divised without a remainder."); } } private void AssociatedObject_ScrollChanged(object sender, ScrollChangedEventArgs e) { const double stepSize = 62; var scrollViewer = (ScrollViewer)sender; var steps = Math.Round(scrollViewer.VerticalOffset / stepSize, 0); var scrollPosition = steps * stepSize; if (scrollPosition >= scrollViewer.ScrollableHeight) { scrollViewer.ScrollToBottom(); return; } scrollViewer.ScrollToVerticalOffset(scrollPosition); } }

您可以这样使用它:

<*>

我这样做是为了确保scrollbar1.ValueChanged上的整数:

scrollbar1.Value = Math.Round(scrollbar1.Value, 0, MidpointRounding.AwayFromZero)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top