2010-01-22 19 views

risposta

11

Risposta breve è "modificare il modello della barra di scorrimento".

La risposta lunga è ... che aggiungerei un oggetto ItemControl nel modello del controllo ScrollBar. Vorrei mettere questo ItemsControl in cima al modello con il suo IsHitTestVisible impostato su false in modo che non catturasse gli eventi del mouse.

Quindi vorrei utilizzare una tela come ItemsPanelTemplate per poter posizionare correttamente i punti. Userei il databinding con la proprietà ItemsSource di ItemsControl e un DataTemplate per rendere ogni elemento con un'immagine.

Ecco un esempio che ho utilizzato con Blend. Ovviamente non è completo (per esempio non gestisce l'evento del mouse), ma spero che sarà un punto di partenza per te.

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

Come hai risolto il problema con il ridimensionamento della barra di scorrimento? I marcatori sono ancora nella stessa posizione ma la finestra ha un'altra dimensione in modo che i marcatori si trovino in una posizione sbagliata. Non so come risolverlo. –

+1

Hmm, in questo caso, penso che potrebbe essere necessario sottoclasse la classe ScrollBar per essere in grado di gestire l'evento SizeChanged (o simile non ho il nome esatto) per ricalcolare la posizione dei marcatori. – japf

1

Per contribuire a japfs RISPOSTA: Ho risolto l'aggiornamento sul tema di ridimensionamento: È possibile utilizzare japfs Stile e applicare un'ItemsSource alla ItemControl:

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

Basta fare sure Positions è di tipo ObservableCollection e le posizioni vengono ricalcolate in SizeChanged-event. Inoltre, nel caso in quella chiamata (interfaccia INotifyPropertyChanged che dovrebbe tuo ViewModel implementare)

OnPropertyChanged("Positions"); 

provato con un primo elenco, ma che non ha aggiornato correttamente. Ha funzionato correttamente con ObservableCollection.