2009-10-28 24 views
12

¿Es posible cambiar la cantidad de desplazamiento del WPF ScrollViewer? Simplemente me pregunto si es posible cambiar el scrollviewer para que, al usar la rueda del mouse o las flechas del scrollviewer, se pueda cambiar la cantidad de desplazamiento incremental.Wpf ScrollViewer Volumen de desplazamiento

Respuesta

12

La respuesta breve es: no hay forma de hacerlo sin escribir un código de desplazamiento personalizado, pero no dejes que te asuste, no es tan difícil.

ScrollViewer funciona desplazándose mediante unidades físicas (es decir, píxeles) o interactuando con una implementación de IScrollInfo para utilizar unidades lógicas. Esto se controla mediante la configuración the CanContentScroll property, donde un valor de falso significa "desplazar el contenido usando unidades físicas" y un valor de verdadero significa "desplazar el contenido lógicamente".

Entonces, ¿cómo desplaza ScrollViewer el contenido lógicamente? Al comunicarse con una implementación IScrollInfo. Así es como se puede controlar exactamente cuánto se desplaza el contenido de su panel cuando alguien realiza una acción lógica. Take a look at the documentation for IScrollInfo para obtener una lista de todas las unidades lógicas de medición que pueden solicitarse para desplazarse, pero como ha mencionado la rueda del mouse, le interesarán principalmente los métodos MouseWheelUp/Down/Left/Right.

0

Puede implementar un comportamiento en el scrollviewer. En mi caso CanContentScroll no funcionó. La siguiente solución funciona para desplazarse con la rueda del mouse y arrastrar la barra de desplazamiento.

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

Se podría utilizar de esta manera:

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

que hice esto para asegurarse de números enteros en scrollbar1.ValueChanged:

scrollbar1.Value = Math.Round(scrollbar1.Value, 0, MidpointRounding.AwayFromZero) 
Cuestiones relacionadas