Frage

Ist es möglich, die Menge, die die WPF Scroll Rollen zu ändern? Ich frage mich nur, ob es möglich ist, den Scroll zu ändern, so dass, wenn das Mausrad oder die Scrollpfeile verwendet wird, kann die Menge der inkrementellen Scrollen geändert werden.

War es hilfreich?

Lösung

Die kurze Antwort lautet: Es gibt keine Möglichkeit, dies einige benutzerdefinierte Scrollen Code ohne das Schreiben zu tun, aber lassen Sie sich nicht, dass abschrecken es so schwer ist nicht alles

.

, um die Scroll arbeitet entweder unter Verwendung von physikalischen Einheiten Scrolling (d.h. Pixel) oder durch Umsetzung mit einer IScrollInfo Eingriff logische Einheiten zu verwenden. Dies wird durch die Einstellung der CanContentScroll Eigenschaft gesteuert , wo der Wert false bedeutet „bewegt den Inhalt physikalische Einheiten mit“ und dem Wert true bedeutet „bewegt den Inhalt logisch“.

Wie funktioniert blättern die Scroll den Inhalt logisch? Durch die Kommunikation mit einer IScrollInfo Implementierung. Also das ist, wie Sie genau übernehmen könnte, wie viel Sie den Inhalt Ihrer Platte scrollt, wenn jemand eine logische Aktion ausführt. Werfen Sie einen Blick in die Dokumentation für IScrollInfo eine Liste aller logischen Einheiten der Messprotokoll erhalten, die blättern angefordert werden kann, aber da Sie das Mausrad erwähnt werden Sie vor allem in den MouseWheelUp / Ab / links / Rechts Methoden interessiert sein.

Andere Tipps

Hier ist eine einfache, vollständige und Arbeits WPF ScrollViewer Klasse, die eine Daten-bindable SpeedFactor Eigenschaft zur Einstellung des Mausrads Empfindlichkeit aufweist. Einstellen SpeedFactor bis 1,0 bedeutet identisches Verhalten auf die WPF ScrollViewer. Der Standardwert für die Abhängigkeitseigenschaft ist 2.5 , die für sehr schnelles Rad Scrollen ermöglicht.

Natürlich können Sie auch weitere nützliche Funktionen erstellen, indem Sie sich an die SpeedFactor Eigenschaft Bindung, das heißt, auf einfache Weise dem Benutzer zu erlauben, den Multiplikator zu steuern.

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;
        }
    }
};

Komplette XAML-Demo von 'schnell Scrollen mit dem Mausrad' von rund 3200 Datenelementen:

<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>

Fast Mausrad:

Sie können ein Verhalten auf dem Scroll implementieren. In meinem Fall CanContentScroll funktionierte nicht. Die Lösung unter Arbeiten für mit dem Mausrad sowie draging die Scrollbar.

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);
    }
}

Sie würde es so verwenden:

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

Ich habe diese, um sicherzustellen, ganze Zahlen auf scrollbar1.ValueChanged:

scrollbar1.Value = Math.Round(scrollbar1.Value, 0, MidpointRounding.AwayFromZero)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top