wpf - XAML ScrollViewer ControlTemplate 中的 SmallChange 无效

标签 wpf xaml

我创建了一个基本的 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,但最终我希望对滚动进行比整页更好的控制。

最佳答案

其原因是 ScrollViewerScrollBar 中实现的特殊逻辑。

如果滚动条是独立的,则仅考虑滚动 ScrollBar.SmallChange 属性。这意味着,当它位于 ScrollViewer 之外时。

如果您查看 ScrollViewer.OnApplyTemplate method ,您会注意到以下内容:

public override void OnApplyTemplate()
{
    // ...
    ScrollBar scrollBar = GetTemplateChild(HorizontalScrollBarTemplateName) as ScrollBar;

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

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

如果 ScrollViewer 在其内部找到滚动条,则会将其 IsStandalone(internal)属性设置为 false,禁用滚动条的滚动命令处理。相反,ScrollViewer 接管滚动命令处理,但它忽略了 ScrollBar 的一些属性,包括 SmallChange 属性。

TL;DR 这对于 ScrollViewer 内部的滚动条不起作用。您可以更改模板,因此使用两个“外部”滚动条。但是,您需要手动将这些滚动条与 ScrollViewer 连接起来。

关于wpf - XAML ScrollViewer ControlTemplate 中的 SmallChange 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30600318/

相关文章:

c# - 如何使用 MVVM WPF 架构创建自定义用户控件

c# - 通过绑定(bind)部分填充 MenuItem

c# - 为什么 wpf UpdateSourceTrigger 没有明确绑定(bind)?

xaml - 删除弹出控件内 ListViewItem 上的填充

c# - 在 Windows 8 Metro App 中拖放图像

c# - 如何将标签内容与查询中的值绑定(bind)?

wpf - 每次打开时强制上下文菜单重新创建子控件

c# - 如何在 MAUI 中刷新 XAML View ?

xaml - 按钮内的 Xamarin.Forms TextBlock。自定义文本换行

c# - 我的代码是否展示了良好的 WPF 实践?