XAML ScrollViewer 控件模板中的 SmallChange 无效。

6

我已经创建了一个基本的Windows桌面WPF应用程序。在主窗口中,我已将以下内容添加为窗口的主体:

    <ScrollViewer Template="{DynamicResource ScrollViewerControlTemplate1}">
        <ScrollViewer.Resources>
            <ControlTemplate x:Key="ScrollViewerControlTemplate1" TargetType="{x:Type ScrollViewer}">
                <Grid x:Name="Grid" Background="{TemplateBinding Background}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
                    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
                    <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" SmallChange="40000"/>
                    <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
                </Grid>
            </ControlTemplate>
        </ScrollViewer.Resources>
        <Grid Margin="20">
            <Grid.RowDefinitions>
                <RowDefinition Height="300"/>
                <RowDefinition Height="300"/>
                <RowDefinition Height="300"/>
                <RowDefinition Height="300"/>
                <RowDefinition Height="300"/>
            </Grid.RowDefinitions>

            <Border Grid.Row="0" Background="SteelBlue"/>
            <Border Grid.Row="1" Background="Peru"/>
            <Border Grid.Row="2" Background="Goldenrod"/>
            <Border Grid.Row="3" Background="Tomato"/>
            <Border Grid.Row="4" Background="IndianRed"/>
        </Grid>

    </ScrollViewer>

您会注意到在PART_VerticalScrollbar上,我设置了SmallChange="40000"(一个任意大的数字)。然而,当我点击滚动条上的向上/向下箭头时,它所做的改变非常小,就像在设置SmallChange之前一样。 我已经多次阅读了文档,但无法弄清楚为什么这对ScrollViewer滚动的数量没有任何影响。有什么想法吗?请注意,我可以更改ScrollBar模板并将这些按钮调用的命令更改为ScrollBar.PageUpCommand而不是ScrollBar.LineUpCommand,但最终我希望比整个页面更好地控制滚动。
2个回答

1
这是由ScrollViewerScrollBar中实现的特殊逻辑所致。
只有当滚动条是独立的时,ScrollBar.SmallChange属性才会被考虑用于滚动。也就是说,当它在ScrollViewer之外时。
如果您查看ScrollViewer.OnApplyTemplatemethod,您将会注意到以下内容:
public override void OnApplyTemplate()
{
    // ...
    ScrollBar scrollBar = GetTemplateChild(HorizontalScrollBarTemplateName) as ScrollBar;

    if (scrollBar != null)
        scrollBar.IsStandalone = false;

    // Same for the vertical scroll bar
    // ...
}

如果一个ScrollViewer在其内部找到滚动条,则将它们的IsStandaloneinternal)属性设置为false,这会禁用滚动条的滚动命令处理。相反,ScrollViewer接管滚动命令处理,但忽略一些ScrollBar的属性,包括SmallChange属性。 TL;DR 对于ScrollViewer内部的滚动条,这种方法不起作用。你可以更改模板以使用两个“外部”滚动条。但是,然后你需要手动连接这些滚动条与ScrollViewer

0

我怀疑你的自定义控件模板没有被使用,可能是因为引用方式不正确。我建议将XAML更改为以下内容:

<ScrollViewer>
    <ScrollViewer.Template>
        <ControlTemplate TargetType="{x:Type ScrollViewer}">
            <Grid ...>
                ...
            </Grid>
        </ControlTemplate>
    </ScrollViewer.Template>

    ... ScrollViewer content goes here

</ScrollViewer>

基本上,直接设置控件的模板,而不是使用动态资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接