我有一个长滚动查看器,我想在滚动条上用小图像标记重要点。如果单击图像,滚动条将跳转到相应的内容。
我已经在 Eclipse 和Chrome等一些应用程序中看到了此功能,并且想知道如何使用 WPF 重现它。
我有一个长滚动查看器,我想在滚动条上用小图像标记重要点。如果单击图像,滚动条将跳转到相应的内容。
我已经在 Eclipse 和Chrome等一些应用程序中看到了此功能,并且想知道如何使用 WPF 重现它。
简短的回答是“更改 ScrollBar 的模板”。
长答案是......我会在 ScrollBar 控件的模板中添加一个 ItemsControl。我会将这个 ItemsControl 放在模板的顶部,并将其 IsHitTestVisible 设置为 false,这样它就不会捕获鼠标事件。
然后我会使用 Canvas 作为 ItemsPanelTemplate 以便能够正确放置点。我会将数据绑定与 ItemsControl 的 ItemsSource 属性和 DataTemplate 一起使用,以便用图像呈现每个元素。
这是我使用 Blend 做的一个示例。当然它不完整(例如它不处理鼠标事件),但我希望它会成为你的起点。
(来源:japf.fr)
<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>
To contribute to japfs answer: I solved the update on resize issue: You can use japfs Style and apply a ItemsSource to the ItemControl:
ItemsSource="{Binding Positions, UpdateSourceTrigger=PropertyChanged}"
Just make sure Positions is of type ObservableCollection and the positions are recalculated in SizeChanged-event. Additionally in that event call (INotifyPropertyChanged interface which should your ViewModel implement)
OnPropertyChanged("Positions");
Tried it with a List first, but that did not update correctly. Worked with ObservableCollection just fine.