除非有人对这种行为有更好的解释,否则这对我来说真的是一个奇怪的错误。
ScrollViewer
(PART_ContentHost) 内部使用Template
类似:
<ControlTemplate 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.Row="1"
Grid.Column="1"
Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="0"
Grid.Column="0"
Margin="{TemplateBinding Padding}"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Row="0"
Grid.Column="1"
AutomationProperties.AutomationId="VerticalScrollBar"
Cursor="Arrow"
Maximum="{TemplateBinding ScrollableHeight}"
Minimum="0"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset,
Mode=OneWay,
RelativeSource={RelativeSource TemplatedParent}}" />
<ScrollBar x:Name="PART_HorizontalScrollBar"
Grid.Row="1"
Grid.Column="0"
AutomationProperties.AutomationId="HorizontalScrollBar"
Cursor="Arrow"
Maximum="{TemplateBinding ScrollableWidth}"
Minimum="0"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding HorizontalOffset,
Mode=OneWay,
RelativeSource={RelativeSource TemplatedParent}}" />
</Grid>
</ControlTemplate>
有趣的是:
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="0"
Grid.Column="0"
Margin="{TemplateBinding Padding}"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
现在要解决您的问题,您只需将 Margin 设置为 0 而不是,{TemplateBinding Padding}
您将获得所需的输出。
但是为什么我们需要这样做呢?
TemplateBinding Padding
似乎忽略了直接在ScrollViewer
内部范围内设置的值,并选择从 Parent( Button
) 继承的 Padding 值,即 15。
好吧,这很奇怪,但更糟糕的是它只适用于 Padding。Foreground
, Background
,Margin
直接设置时都很好,ScrollViewer
它们会覆盖TextBox
's 字段。我什至确认将使用中的Padding
集合直接移动TextBox
到默认样式设置器,以查看是否存在某些优先级情况。
似乎没有。得到相同的输出。
填充定义在System.Windows.Controls.Control
哪个类 Foreground 和 BackgroundScrollViewer
继承自同一个类。不知道为什么单独填充的行为不同。
我还尝试将演示者更改为类似
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="0"
Grid.Column="0"
Margin="{TemplateBinding Margin}"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"
Content="{TemplateBinding Padding}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
它打印的是 15,15,15,15。不会为Margin
.
与{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}, Path=Padding}
绑定相同的效果。
我看到一篇帖子说ScrollViewer
不会将其上设置的属性传递给它的孩子。不要真正明白这一点,因为如果是这样的话,如何超越Background
,Margin
并且可以很好地超越?有什么特别之处Padding
?如果它是有效的行为,我真的不知道如何在没有模板的情况下摆脱这种行为ScrollViewer
,这是一个令人困惑的实现。