如何将图像“placemarkers”放在WPF的滚动条中?

时间:2010-01-22 04:30:09

标签: wpf image scrollbar scrollviewer

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

我在Eclipse和Chrome这样的应用程序中看到了这个功能,并想知道如何使用WPF重现它。

2 个答案:

答案 0 :(得分:12)

简短回答是“更改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>

答案 1 :(得分:1)

为japfs答案做出贡献: 我解决了调整大小问题的更新: 您可以使用japfs Style并将ItemsSource应用于ItemControl:

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

只需确保Positions的类型为ObservableCollection,并在SizeChanged-event中重新计算位置。另外在那个事件调用中(你的ViewModel应该实现的INotifyPropertyChanged接口)

OnPropertyChanged("Positions");

首先使用List尝试,但没有正确更新。使用ObservableCollection就好了。