2010-06-25 8 views
6

Ich versuche den Algorithmus zu ermitteln, der mit der Größenanpassung des WPF-Bildlaufleisten-Thumb-Elements verbunden ist.Einstellen der Bildlaufleisten-Thumb-Größe

Das Thumb-Element kann mithilfe der Scrollbar.ViewportSize-Eigenschaft skaliert werden, ist aber wiederum mit den Werten Scrollbar.Minimum und Scrollbar.Maximum verknüpft.

Was ich bisher entdeckt ist:

Für ein Minimum und Maximum von und , ein Viewport von:

0 - Thumb Mindestgröße
5 - Daumen ca. 25 % des verfügbaren Tracks
10 - Thumb etwa 50% der verfügbaren Spur
100 - Thumb etwa 75% der verfügbaren Spur
1000 - Thumb etwa 90% des verfügbaren Tracks
10000 - Thumb füllt den verfügbaren Track.

[Anmerkung: Diese Zahlen sind nur aus meinem groben Versuch und Irrtum]

Idealerweise kann Ich mag würde in der Lage sein, einen Algorithmus zu haben, wo die Minimal- und Maximalwerte für die Scrollbar I die Daumen gesetzt Größe, um genau x% der verfügbaren Spur zu sein.

Kann mir jemand dabei helfen?

Danke.

+0

Sie nicht die Daumengröße von nur Min und Max bestimmen kann, .Sie benötigen auch die relative Ansichtsfenstergröße (wie viel von dem [Min, Max] Intervall in das Ansichtsfenster passt): thumbSizePercent = Min (100, 100 * ViewportSize/(MaxValue-MinValue)) – Andy

Antwort

11

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

Thumbsize = (Viewport/(Maximum-Minimum + Viewport)) × trackLength

oder Umordnen für Viewport:

Viewport = thumbSize × (Maximum-Minimum)/(TrackLength-thumbSize)

Sie haben dieses Problem schon gefunden, aber ich dachte, ich poste für den Fall, dass andere hier enden.

+1

Wenn Sie nur relative Größe benötigen: 'viewportSize = (Maximum - Minimum) * p/(1 - p) ', wobei' p 'zwischen 0,0 und 1,0 liegt. –

4

Auf meiner Seite habe ich eine minimale Daumenlänge beibehalten, weil Touch-Eingaben erfordern einen Daumen von einer minimalen Größe, um Touch-optimiert werden.

Sie können ein ScrollViewer ControlTemplate definieren, das die TouchScrollBar als horizontale und vertikale ScrollBar verwendet.

Siehe UpdateViewPort-Methode für die Mathematik.

Sorry, ich sehe nicht den Anwendungsfall für explizit die Scrollbar Daumen Einstellung einen Prozentsatz der Spurlänge zu bedecken

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

Eine andere Möglichkeit zum Einstellen der MinWidth oder MinHeight des Thumb wird hier gezeigt: http://msdn.microsoft.com/en-us/library/bb613595.aspx – Kolky

+0

@Nadzzz: Ihr Code hat eine Reihe von Problemen und wird nicht funktionieren wie erwartet überhaupt. Am wichtigsten ist, dass Sie die ViewportSize der ScrollBar ändern. Sie wird nie wieder berechnet, wenn sich die Anzahl der Elemente in der Liste ändert. Dies funktioniert möglicherweise nur für statische Daten in einem statischen Layout, nicht für etwas, das sich zur Laufzeit etwas ändern könnte. – ygoe

+0

@Kolky: Das Beispiel von Microsoft funktioniert auch nicht. Es löst alle möglichen Ausnahmen aus. Ich weiß nicht, ob es überhaupt das Richtige tun würde, wenn es funktionierte. Ich kann keine MinHeight-Logik darin sehen. – ygoe