문제

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>

빠른 마우스 휠 :

enter image description here

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($"{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);
    }
}

당신은 다음과 같이 사용할 것입니다.

<ScrollViewer MaxHeight="248"
              VerticalScrollBarVisibility="Auto">
    <i:Interaction.Behaviors>
        <behaviors:StepSizeBehavior StepSize="62" />
    </i:Interaction.Behaviors>

나는 scrollbar1.valuechanged에서 정수를 보장하기 위해 이것을했다.

scrollbar1.Value = Math.Round(scrollbar1.Value, 0, MidpointRounding.AwayFromZero)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top