2010-06-25 7 views
6

Estoy intentando resolver el algoritmo asociado con el tamaño del elemento de pulgar de la barra de desplazamiento de WPF.Configuración de la barra de desplazamiento Tamaño de pulgar

El elemento thumb se puede dimensionar utilizando la propiedad Scrollbar.ViewportSize, pero a su vez está relacionado con los valores Scrollbar.Minimum y Scrollbar.Maximum.

Lo que he descubierto hasta ahora es:

Para un mínimo y máximo de y , un ViewportSize de:

0 - Pulgar mínimo
5 - Pulgar aproximadamente el 25 % de la pista disponible
10 - Pulgar aproximadamente el 50% de la pista disponible
100 - Pulgar aproximadamente el 75% de la pista disponible
1000 - Pulgar aproximadamente el 90% de la pista disponible
10000 - El pulgar llena la pista disponible.

[Nota: estas cifras son sólo de mi ensayo y error áspera]

Idealmente me gustaría ser capaz de tener un algoritmo donde Dados los valores mínimo y máximo de la barra de desplazamiento puedo configurar el pulgar tamaño para ser exactamente x% de la pista disponible.

¿Alguien puede ayudar con esto?

Gracias.

+0

No se puede determinar el tamaño del pulgar de sólo mínimo y máximo .También necesita el tamaño relativo de la ventana gráfica (cuánto del intervalo [Min, Max] cabe en la ventana gráfica): thumbSizePercent = Min (100, 100 * ViewportSize/(MaxValue-MinValue)) – Andy

Respuesta

11

Desde: http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.track(VS.90).aspx

thumbSize = (viewportSize/(máximo-mínimo + viewportSize)) × trackLength

o re-organización para viewportSize:

viewportSize = thumbSize × (maximum-minimum)/(trackLength-thumbSize)

Ya lo ha encontrado, pero pensé en publicarlo en caso de que otros terminen aquí.

+1

Si solo necesita el tamaño relativo: 'viewportSize = (máximo - mínimo) * p/(1 - p) ', donde' p' está entre 0.0 y 1.0. –

4

Por mi parte, conservé una longitud mínima de pulgar porque las entradas táctiles requieren un pulgar de un tamaño mínimo para optimizar el tacto.

Puede definir una ScrollViewer ControlTemplate que utilizará TouchScrollBar como su barra de desplazamiento horizontal y vertical.

Consulte el método UpdateViewPort para las matemáticas.

Lo sentimos, no veo el caso de uso para establecer explícitamente la barra de desplazamiento para cubrir un porcentaje de la longitud de la pista

public class TouchScrollBar : System.Windows.Controls.Primitives.ScrollBar 
{ 
    #region Fields 

    #region Dependency properties 

    public static readonly DependencyProperty MinThumbLengthProperty = 
     DependencyProperty.Register 
     ("MinThumbLength", typeof(double), typeof(TouchScrollBar), new UIPropertyMetadata((double)0, OnMinThumbLengthPropertyChanged)); 

    #endregion 

    private double? m_originalViewportSize; 

    #endregion 

    #region Properties 

    public double MinThumbLength 
    { 
     get { return (double)GetValue(MinThumbLengthProperty); } 
     set { SetValue(MinThumbLengthProperty, value); } 
    } 

    #endregion 

    #region Constructors 

    public TouchScrollBar() 
    { 
     SizeChanged += OnSizeChanged; 
    } 

    private bool m_trackSubscribed; 
    void OnSizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     SubscribeTrack(); 
    } 

    private void SubscribeTrack() 
    { 
     if (!m_trackSubscribed && Track != null) 
     { 
      Track.SizeChanged += OnTrackSizeChanged; 
      m_trackSubscribed = true; 
     } 

    } 

    #endregion 

    #region Protected and private methods 

    #region Event handlers 

    #region Dependency properties event handlers 

    private void OnMinThumbLengthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     TouchScrollBar instance = d as TouchScrollBar; 
     if(instance != null) 
     { 
      instance.OnMinThumbLengthChanged(e); 

     } 
    } 

    #endregion 

    protected void OnTrackSizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     SubscribeTrack(); 
     UpdateViewPort(); 
    } 

    protected override void OnMaximumChanged(double oldMaximum, double newMaximum) 
    { 
     base.OnMaximumChanged(oldMaximum, newMaximum); 

     SubscribeTrack(); 
     UpdateViewPort(); 
    } 

    protected override void OnMinimumChanged(double oldMinimum, double newMinimum) 
    { 
     base.OnMinimumChanged(oldMinimum, newMinimum); 

     SubscribeTrack(); 
     UpdateViewPort(); 
    } 

    protected void OnMinThumbLengthChanged(DependencyPropertyChangedEventArgs e) 
    { 
     SubscribeTrack(); 
     UpdateViewPort(); 
    } 

    #endregion 

    private void UpdateViewPort() 
    { 
     if(Track != null) 
     { 
      if(m_originalViewportSize == null) 
      { 
       m_originalViewportSize = ViewportSize; 
      } 

      double trackLength = Orientation == Orientation.Vertical ? Track.ActualHeight : Track.ActualWidth; 
      double thumbHeight = m_originalViewportSize.Value/(Maximum - Minimum + m_originalViewportSize.Value) * trackLength; 
      if (thumbHeight < MinThumbLength && !double.IsNaN(thumbHeight)) 
      { 
       ViewportSize = (MinThumbLength * (Maximum - Minimum))/(trackLength + MinThumbLength); 
      } 
     } 
    } 


    #endregion 
} 

}

+2

Otra forma de establecer MinWidth o MinHeight del Thumb se muestra aquí: http://msdn.microsoft.com/en-us/library/bb613595.aspx – Kolky

+0

@Nadzzz: Su código tiene una serie de problemas y no trabajar como se espera en absoluto. Lo más importante es que cambia el ViewportSize de ScrollBar y nunca volverá a calcularse cuando cambie la cantidad de elementos en la lista. Esto solo puede funcionar para datos estáticos en un diseño estático, no para nada que pueda cambiar un poco en el tiempo de ejecución. – ygoe

+0

@Kolky: Ese ejemplo de Microsoft tampoco funciona. Arroja todo tipo de excepciones. No sé si haría lo correcto en absoluto, si funcionó. No puedo ver ninguna lógica MinHeight en él. – ygoe

Cuestiones relacionadas