2010-01-22 6 views

Répondre

11

La réponse courte est "changer le modèle du ScrollBar". La réponse longue est ... Que j'ajouterais un ItemsControl dans le modèle du contrôle ScrollBar. Je placerais ce ItemsControl au-dessus du modèle avec son IsHitTestVisible défini sur false afin qu'il ne capture pas les événements de souris. Puis j'utiliserais un Canvas comme ItemsPanelTemplate afin de pouvoir placer les spots correctement. J'utiliserais la liaison de données avec la propriété ItemsSource de ItemsControl et un DataTemplate afin de rendre chaque élément avec une image.

Voici un exemple que j'ai fait en utilisant Blend. Bien sûr, ce n'est pas complet (il ne gère pas l'événement souris par exemple), mais j'espère que ce sera un point de départ pour vous.

alt text http://www.japf.fr/download/scrollbars.png

<ControlTemplate TargetType="{x:Type ScrollBar}"> 
    <Grid SnapsToDevicePixels="true" Background="{TemplateBinding Background}"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/> 
      <ColumnDefinition Width="0.00001*"/> 
      <ColumnDefinition MaxWidth="{DynamicResource {x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}}"/> 
     </Grid.ColumnDefinitions> 
     <RepeatButton Style="{StaticResource ScrollBarButton}" Command="{x:Static ScrollBar.LineLeftCommand}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="LeftArrow"/> 
     <Track x:Name="PART_Track" Grid.Column="1" d:IsHidden="True"> 
      <Track.Thumb> 
       <Thumb Style="{StaticResource ScrollBarThumb}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="HorizontalGripper"/> 
      </Track.Thumb> 
      <Track.IncreaseRepeatButton> 
       <RepeatButton Style="{StaticResource HorizontalScrollBarPageButton}" Command="{x:Static ScrollBar.PageRightCommand}"/> 
      </Track.IncreaseRepeatButton> 
      <Track.DecreaseRepeatButton> 
       <RepeatButton Style="{StaticResource HorizontalScrollBarPageButton}" Command="{x:Static ScrollBar.PageLeftCommand}"/> 
      </Track.DecreaseRepeatButton> 
     </Track> 
     <ItemsControl Grid.Column="1" HorizontalAlignment="Stretch"> 
      <sys:Double>10</sys:Double> 
      <sys:Double>50</sys:Double> 
      <sys:Double>100</sys:Double> 
      <sys:Double>140</sys:Double> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Rectangle Fill="Orange" Width="3" Height="16"/> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
      <ItemsControl.ItemContainerStyle> 
       <Style TargetType="ContentPresenter"> 
        <Setter Property="Canvas.Left" Value="{Binding }" /> 
       </Style> 
             </ItemsControl.ItemContainerStyle> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <Canvas/> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
     </ItemsControl> 
     <RepeatButton Style="{StaticResource ScrollBarButton}" Grid.Column="2" Command="{x:Static ScrollBar.LineRightCommand}" Microsoft_Windows_Themes:ScrollChrome.ScrollGlyph="RightArrow" d:IsHidden="True"/> 
    </Grid> 
</ControlTemplate> 
+0

Comment avez-vous résolu le problème de redimensionnement de la barre de défilement? Les marqueurs sont toujours sur la même position mais la fenêtre a une autre taille donc les marqueurs sont dans une mauvaise position. Je ne sais pas comment résoudre ça. –

+1

Hmm, dans ce cas, je pense que vous pourriez avoir besoin de sous-classer la classe ScrollBar pour pouvoir gérer l'événement SizeChanged (ou similaire je n'ai pas le nom exact) pour recalculer la position des marqueurs. – japf

1

Contribuer à japfs Réponse: Je résolu la mise à jour sur la question de redimensionnement: Vous pouvez utiliser japfs style et appliquer une ItemsSource au ItemControl:

ItemsSource="{Binding Positions, UpdateSourceTrigger=PropertyChanged}" 

Assurez sure Positions est de type ObservableCollection et les positions sont recalculées dans SizeChanged-event. De plus, dans cet appel d'événement (interface INotifyPropertyChanged qui devrait mettre en œuvre votre ViewModel)

OnPropertyChanged("Positions"); 

Essayé avec une liste d'abord, mais cela n'a pas correctement mise à jour. Travaillé avec ObservableCollection très bien.

Questions connexes