2010-01-22 65 views

回答

11

简短回答是“更改ScrollBar的模板”。

长答案是...我会在ScrollBar控件的模板中添加一个ItemsControl。我将这个ItemsControl放置在模板的顶部,将其IsHitTestVisible设置为false,以便它不捕获鼠标事件。

然后,我会使用Canvas作为ItemsPanelTemplate,以便能够正确放置点。我将使用ItemsControl的ItemsSource属性和DataTemplate的数据绑定为了呈现每个元素与图像。

这是我使用Blend的一个示例。当然,它并不完整(例如,它不处理鼠标事件),但我希望它会成为您的起点。

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

您是如何解决调整滚动条大小的问题的?标记仍处于相同位置,但窗口具有另一个大小,因此标记位置错误。不知道如何解决这个问题。 – 2017-03-14 15:04:04

+1

嗯,在这种情况下,我想你可能需要继承ScrollBar类以便能够处理SizeChanged事件(或类似的我没有确切的名字)来重新计算标记的位置。 – japf 2017-03-15 16:01:04

1

为了促进japfs回答: 我解决了在调整大小问题的更新: 您可以使用japfs样式和应用的ItemsSource到ItemControl:

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

只是要确定位置的类型是ObservableCollection,并且位置将在SizeChanged事件中重新计算。此外,在这种情况下调用(INotifyPropertyChanged接口应您的视图模型实现)

OnPropertyChanged("Positions"); 

用List试了一下第一,但没有正确更新。使用ObservableCollection就好了。