11

我有一个长滚动查看器,我想在滚动条上用小图像标记重要点。如果单击图像,滚动条将跳转到相应的内容。

我已经在 Eclipse 和Chrome等一些应用程序中看到了此功能,并且想知道如何使用 WPF 重现它。

4

2 回答 2

12

简短的回答是“更改 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>
于 2010-01-22T13:32:41.670 回答
1

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.

于 2017-04-21T16:41:15.280 回答