如何在WPF中的滚动条内放置图像“placemarkers”?
问题描述:
我有一个长的滚动查看器,我想用滚动条上的小图像来标记重要的点。如果图像被点击,滚动条将跳转到相应的内容。如何在WPF中的滚动条内放置图像“placemarkers”?
我已经在Eclipse和Chrome等几个应用程序中看到过这个功能,并想知道如何用WPF重现它。
答
简短回答是“更改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>
答
为了促进japfs回答: 我解决了在调整大小问题的更新: 您可以使用japfs样式和应用的ItemsSource到ItemControl:
ItemsSource="{Binding Positions, UpdateSourceTrigger=PropertyChanged}"
只是要确定位置的类型是ObservableCollection,并且位置将在SizeChanged事件中重新计算。此外,在这种情况下调用(INotifyPropertyChanged接口应您的视图模型实现)
OnPropertyChanged("Positions");
用List试了一下第一,但没有正确更新。使用ObservableCollection就好了。
您是如何解决调整滚动条大小的问题的?标记仍处于相同位置,但窗口具有另一个大小,因此标记位置错误。不知道如何解决这个问题。 – 2017-03-14 15:04:04
嗯,在这种情况下,我想你可能需要继承ScrollBar类以便能够处理SizeChanged事件(或类似的我没有确切的名字)来重新计算标记的位置。 – japf 2017-03-15 16:01:04